React Native JSI implementiert Beispielcode für RN und native Kommunikation

React Native JSI implementiert Beispielcode für RN und native Kommunikation

Was ist JSI

React Native JSI (JavaScript Interface) ermöglicht eine schnellere und einfachere Kommunikation zwischen JavaScript und nativen Modulen. Es ist auch der Kernteil der Fabric-UI-Schicht und des Turbo-Moduls in der neuen Architektur von React Native.

Was ist anders an JSI

JSI entfernt die Brücke zwischen nativem Code und JavaScript-Code und spart außerdem viele JSON-Serialisierungs- und Deserialisierungsvorgänge, wenn die beiden Enden sich gegenseitig aufrufen. JSI öffnet neue Türen für die native und JS-Interaktion. Hier sind einige der Funktionen von JSI:

  1. Mit der JavaScript-Schnittstelle können wir Methoden bei der JavaScript-Laufzeit registrieren. Diese Methoden können über das globale Objekt in der JS-Umgebung abgerufen und aufgerufen werden.
  2. Wir können C++ oder OC in iOS und Java in Android verwenden, um diese Registrierungsmethoden zu implementieren.
  3. Native Module, die ursprünglich mit der Bridge-Methode implementiert wurden, können durch Hinzufügen einer C++-Schicht schnell in JSI konvertiert werden.
  4. Die Implementierung unter iOS ist sehr einfach, da C++ und OC problemlos gemischt werden können.
  5. Unter Android müssen wir einige Konvertierungen über JNI durchführen.
  6. Diese Methoden können vollständig synchron sein, was bedeutet, dass Asynchronität nicht zwingend erforderlich ist. erwarten.

Verwenden von JSI in iOS

Als Nächstes werden wir JSI Schritt für Schritt in iOS-Projekten verwenden, um native und JS-Kommunikation zu erreichen.
Erstellen Sie ein neues React Native-Projekt

npx react-native init jsiDemo

iOS-Konfiguration

Erstellen Sie die C++-Dateien example.h und example.cpp im iOS-Projektverzeichnis.
beispiel.h

#ifndef BEISPIEL_H
#define BEISPIEL_H

Namensraum Facebook {
 Namespace jsi {
  Klasse Runtime;
 }
}

Namespace-Beispiel {
 void install(facebook::jsi::Runtime &jsiRuntime);
}
#endif /* BEISPIEL_H */

Beispiel.m
#include "beispiel.h"
#include <jsi/jsi.h>
verwende den Namespace facebook::jsi;
Namespace std verwenden;

Namespace-Beispiel {
 void install(Runtime &jsiRuntime) {  
    auto halloWelt = Funktion::createFromHostFunction(jsiRuntime,
                                                       PropNameID::forAscii(jsiRuntime,
                                                                            "Hallo Welt"),
                                                       0,
                                                       [](Laufzeit &Laufzeit,
                                                          konstanter Wert und dieser Wert,
                                                          const Wert *Argumente,
                                                          size_t Anzahl) -> Wert {
        Zeichenfolge Hallo Welt = "Hallo Welt";
        Rückgabewert (Laufzeit, String::createFromUtf8 (Laufzeit, Hallo Welt));
    });
    
    jsiRuntime.global().setProperty(jsiRuntime, "halloWelt", move(halloWelt));
    
 }
}

Im obigen Code erstellen wir eine Methode mit der Methode createFromHostFunction und registrieren sie über die Methode setProperty bei der JS-Laufzeit.
Als Nächstes müssen wir ein Modul erstellen und die Installationsmethode im Modul ausführen.
Wir erstellen OC-Dateien, SimpleJsi.h, SimpleJsi.mm

SimpleJsi.h

#importieren <React/RCTBridgeModule.h>
@interface SimpleJsi : NSObject <RCTBridgeModul>
@property (nichtatomar, zuweisen) BOOL setBridgeOnMainQueue;
@Ende

SimpleJsi.mm

#importiere "SimpleJsi.h"
#importieren <React/RCTBridge+Private.h>
#importieren <React/RCTUtils.h>
#importieren <jsi/jsi.h>
#importiere "beispiel.h"
#importieren <sys/utsname.h>

verwende den Namespace facebook::jsi;
Namespace std verwenden;

@implementation SimpleJsi

@Synthesebrücke = _Brücke;
@synthesize methodQueue = _methodQueue;

RCT_EXPORT_MODULE()

+ (BOOL) erfordertMainQueueSetup {
    
    gebe JA zurück;
}

- (void)setBridge:(RCTBridge *)bridge {
    _bridge = Brücke;
    _setBridgeOnMainQueue = RCTIsMainQueue();
    [selbstinstallierteBibliothek];
}

- (void)installLibrary {
    
    RCTCxxBridge *cxxBridge = (RCTCxxBridge *)self.bridge;
    
    wenn (!cxxBridge.runtime) {
        
        /**
         * Dies ist ein Workaround zur Installation der Bibliothek
         * sobald Laufzeit verfügbar ist und
         * nicht empfohlen. Wenn Sie zufällige Abstürze in iOS sehen
         * global.xxx nicht gefunden usw. verwenden Sie dies.
         */
        
        Versand nach (Versandzeit (VERSANDZEIT JETZT, 0,001 * NSEC_PER_SEC),
                       dispatch_get_main_queue(), ^{
            /**
             Beim Aktualisieren der App während des Debuggens wird die setBridge
             Methode wird zu früh aufgerufen. Die Laufzeit ist noch nicht bereit
             ziemlich oft. Wir müssen die Bibliothek installieren, sobald die Laufzeit
             verfügbar wird.
             */
            [selbstinstallierteBibliothek];
            
        });
        zurückkehren;
    }
    
    Beispiel::install(*(facebook::jsi::Runtime *)cxxBridge.runtime);
}

@Ende

In der Methode setBridge haben wir die Installationsmethode des Beispiels aufgerufen, um die Methodenregistrierung abzuschließen.

RN-Seitenkonfiguration

App.js ändern

importiere React von „react“;
Importtyp {Node} von „react“;
importiere {Text, Ansicht, Schaltfläche} aus „react-native“;

const App: () => Node = () => {
  const [Ergebnis, setResult] = React.useState();

  const drücken = () => {
    setResult(global.halloWelt());
  };
  zurückkehren (
    // eslint-disable-next-line react-native/keine-inline-stile
    <Ansichtsstil={{Hintergrundfarbe: '#FFFFFF', Höhe: '100%'}}>
      <Ansichtsstil={{height: '10%'}} />
      <Button onPress={drücken} title="Schaltfläche" />
      <Text>{'Helloword aufrufen:' + Ergebnis}</Text>
    </Anzeigen>
  );
};

Standard-App exportieren;

Nach dem Klicken auf die Schaltfläche lautet der Ergebniswert „Hallo Welt“.

Ergebnis

Oben haben wir einen nativen JS-Aufruf implementiert, jedoch ohne Parameter, als Nächstes implementieren wir einen einzelnen Parameteraufruf.

js ruft native Methoden mit Parametern auf

Wir fügen die Registrierung der Multiplikationsmethode in die Installmethode von example.cpp ein und übernehmen die Eingabeparameter aus den Argumenten.

automatische Multiplikation = Funktion::createFromHostFunction(jsiRuntime,
                                                     PropNameID::forAscii(jsiRuntime,
                                                                          "multiplizieren"),
                                                     2,
                                                     [](Laufzeit &Laufzeit,
                                                        konstanter Wert und dieser Wert,
                                                        const Wert *Argumente,
                                                        size_t Anzahl) -> Wert {
        int x = argumente[0].getNumber();
        int y = argumente[1].getNumber();
        Rückgabewert (x * y); 
    });

jsiRuntime.global().setProperty(jsiRuntime, "multiplizieren", verschieben(multiplizieren));

Dann ändern Sie App.js

importiere React von „react“;
Importtyp {Node} von „react“;
importiere {Text, Ansicht, Schaltfläche} aus „react-native“;

const App: () => Node = () => {
  const [Ergebnis, setResult] = React.useState();

  const drücken = () => {
    setzeErgebnis(global.multiply(2, 2));
  };
  zurückkehren (
    // eslint-disable-next-line react-native/keine-inline-stile
    <Ansichtsstil={{Hintergrundfarbe: '#FFFFFF', Höhe: '100%'}}>
      <Ansichtsstil={{height: '10%'}} />
      <Button onPress={drücken} title="Schaltfläche" />
      <Text>{'2*2 = ' + Ergebnis}</Text>
    </Anzeigen>
  );
};

Standard-App exportieren;

Ergebnis

Nativer JS-Aufruf

Native Aufrufe von js werden hauptsächlich über die Methode jsiRuntime.global().getPropertyAsFunction(jsiRuntime, "jsMethod").call(jsiRuntime); implementiert.
Zuerst fügen wir eine JS-Methode in JS hinzu. Wir modifizieren App.js und fügen die Methode jsMethod hinzu.

importiere React von „react“;
Importtyp {Node} von „react“;
importiere {Text, Ansicht, Schaltfläche} aus „react-native“;

const App: () => Node = () => {
  const [Ergebnis, setResult] = React.useState();

  global.jsMethod = () => {
    alert('Hallo jsMethod');
  };

  const drücken = () => {
    setzeErgebnis(global.multiply(2, 2));
  };
  zurückkehren (
    // eslint-disable-next-line react-native/keine-inline-stile
    <Ansichtsstil={{Hintergrundfarbe: '#FFFFFF', Höhe: '100%'}}>
      <Ansichtsstil={{height: '10%'}} />
      <Button onPress={drücken} title="Schaltfläche" />
      <Text>{'2*2 = ' + Ergebnis}</Text>
    </Anzeigen>
  );
};

Standard-App exportieren;

Auf der nativen Seite gehen wir davon aus, dass die js-Methode beim Aufrufen der Anwendung ausgelöst wird, und ändern die Methode applicationWillEnterForeground in AppDelegate.

- (void)applicationWillEnterForeground:(UIApplication *)application {
  SimpleJsi *jsi = [self.bridge Modul für Name:@"SimpleJsi"];
  [jsi-Aufrufjs];
}

Holen Sie sich das SimpleJsi-Objekt über die Methode moduleForName und verwenden Sie dann die Methode calljs in SimpleJsi.

- (void)calljs {
  RCTCxxBridge *cxxBridge = (RCTCxxBridge *)self.bridge;
  Laufzeit &jsiRuntime = *(facebook::jsi::Runtime *)cxxBridge.runtime;
  jsiRuntime.global().getPropertyAsFunction(jsiRuntime, "jsMethod").call(jsiRuntime);
}

Ergebnis

Nativer Aufruf einer JS-Methode mit Parametern

Aufrufe mit mehreren Parametern ähneln Aufrufen mit null Parametern, mit dem Unterschied, dass nach der Aufrufmethode eine Parameterliste hinzugefügt wird.
Zuerst definieren wir die Methode auf der js-Seite und ändern app.js

importiere React von „react“;
Importtyp {Node} von „react“;
importiere {Text, Ansicht, Schaltfläche} aus „react-native“;

const App: () => Node = () => {
  const [Ergebnis, setResult] = React.useState();

  global.jsMethod = () => {
    alert('Hallo jsMethod');
  };

  global.jsMultiply = (x, y) => {
    Alarm('x * y = ' + x * y);
  };

  const drücken = () => {
    setzeErgebnis(global.multiply(2, 2));
  };
  zurückkehren (
    // eslint-disable-next-line react-native/keine-inline-stile
    <Ansichtsstil={{Hintergrundfarbe: '#FFFFFF', Höhe: '100%'}}>
      <Ansichtsstil={{height: '10%'}} />
      <Button onPress={drücken} title="Schaltfläche" />
      <Text>{'2*2 = ' + Ergebnis}</Text>
    </Anzeigen>
  );
};

Standard-App exportieren;

Dann ändern wir den Aufruf des nativen Endes
AppDelegate.m

- (void)applicationWillEnterForeground:(UIApplication *)application {
  SimpleJsi *jsi = [self.bridge Modul für Name:@"SimpleJsi"];
// [jsi calljs];
  : [jsi callJsMultiply:4 y:4];
}

SimpleJsi.m

- (void)callJsMultiply:(int)xy:(int)y {
  RCTCxxBridge *cxxBridge = (RCTCxxBridge *)self.bridge;
  Laufzeit &jsiRuntime = *(facebook::jsi::Runtime *)cxxBridge.runtime;
  jsiRuntime.global().getPropertyAsFunction(jsiRuntime, "jsMultiply").call(jsiRuntime, x, y);
}

Ergebnis

Aufrufen von JS-Funktionsparametern auf der nativen Seite

Um die Funktion im js-Parameter im nativen Code aufzurufen, müssen Sie sie über arguments[i].getObject(runtime).getFunction(runtime).call(runtime, value); ; auslösen.

Zuerst registrieren wir eine neue Methode multiplyWithCallback in example.cpp

auto multiplyWithCallback = Funktion::createFromHostFunction(jsiRuntime,
                                                                 PropNameID::forAscii(jsiRuntime,
                                                                                      "multiplizierenMitCallback"),
                                                                 3,
                                                                 [](Laufzeit &Laufzeit,
                                                                    konstanter Wert und dieserWert,
                                                                    const Wert *Argumente,
                                                                    size_t Anzahl) -> Wert {
        int x = argumente[0].getNumber();
        int y = argumente[1].getNumber();
        //Rückruf aufrufen
        Argumente[2].getObject(Laufzeit).getFunction(Laufzeit).call(Laufzeit, x * y);
        
        Rückgabewert();
        
    });
    
    jsiRuntime.global().setProperty(jsiRuntime, "multiplyWithCallback", verschieben(multiplyWithCallback));

Rufen Sie die js-Seite auf und ändern Sie app.js

importiere React von „react“;
Importtyp {Node} von „react“;
importiere {Text, Ansicht, Schaltfläche} aus „react-native“;

const App: () => Node = () => {
  const [Ergebnis, setResult] = React.useState();

  global.jsMethod = () => {
    alert('Hallo jsMethod');
  };

  global.jsMultiply = (x, y) => {
    Alarm('x * y = ' + x * y);
  };

  const drücken = () => {
    // setzeErgebnis(global.multiply(2, 2));
    global.multiplyWithCallback(4, 5, alertResult);
  };

  const alertResult = res => {
    Alarm (Res);
  };

  zurückkehren (
    // eslint-disable-next-line react-native/keine-inline-stile
    <Ansichtsstil={{Hintergrundfarbe: '#FFFFFF', Höhe: '100%'}}>
      <Ansichtsstil={{height: '10%'}} />
      <Button onPress={drücken} title="Schaltfläche" />
      <Text>{'2*2 = ' + Ergebnis}</Text>
    </Anzeigen>
  );
};

Standard-App exportieren;

Nach dem Klicken auf die Schaltfläche wird „multipleWithCallback“ aufgerufen, um die Methode „alertResult“ an die native Methode zu übergeben.

Ergebnis

Zusammenfassen

Das Obige ist die Einführung von JSI in diesem Artikel. Sie können im offiziellen Konto auf JSI antworten, um die GitHub-Download-Adresse des Codes im Artikel zu erhalten.

Frage

Im Fall von RN Debug kann global.xx die entsprechende Methode nicht finden und ich habe keine Ahnung. Wenn Sie eine Lösung haben, kontaktieren Sie mich bitte, vielen Dank.

Verweise

https://blog.notesnook.com/getting-started-react-native-jsi/
reactnative.maxieewong.com/
https://github.com/react-native-community/discussions-and-proposals/issues/91
ospfranco.com/

Dies ist das Ende dieses Artikels über den Beispielcode für React Native JSI zur Implementierung von RN und nativer Kommunikation. Weitere relevante Inhalte zur nativen Kommunikation von React Native finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, Sie werden 123WORDPRESS.COM auch in Zukunft unterstützen!

Das könnte Sie auch interessieren:
  • React Native und native Android-Kommunikationsmethode

<<:  Zusammenfassung der Wissenspunkte zum Selbststudium der integrierten MySql-Funktionen

>>:  Detaillierte Erläuterung des Installationsprozesses von msf auf einem Linux-System

Artikel empfehlen

Lösen Sie das Problem der Installation von Theano auf Ubuntu 19

Lösung: Ändern Sie die Datei setup.py direkt in d...

Was wir über absolute und relative CSS-Werte zu sagen haben

In der Einleitung steht: Absolute sagte: „Relativ...

So konfigurieren Sie den Tomcat-Server für Eclipse und IDEA

Tomcat-Serverkonfiguration Jeder, der das Web ken...

Informationen zu UDP in Linux

Inhaltsverzeichnis 1. Einführung in UDP und Linux...

CSS-Anfänger-Tutorial: Hintergrundbild füllt den gesamten Bildschirm

Wenn Sie möchten, dass die gesamte Benutzeroberfl...

Detaillierte Verwendung von Echarts in vue2 vue3

Inhaltsverzeichnis 1. Installation 2. Verwenden S...

Anwendung schöner Stylesheets bei der Erstellung von XHTML+CSS-Webseiten

Dies ist ein Artikel, der vor langer Zeit geschrie...

Detaillierte Prozessanalyse der Docker-Bereitstellung des Snail-Cinema-Systems

Umwelterklärung Host-Betriebssystem: Cetnos7.9 Mi...

So stellen Sie ein Angular-Projekt mit Docker bereit

Es gibt zwei Möglichkeiten, Angular-Projekte mit ...

CSS horizontale Zentrierung und Begrenzung der maximalen Breite

Eine CSS-Layout- und Stilfrage: Wie kann man die ...