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

Tutorial zur Installation und Konfiguration von MySQL 5.7 unter CentOS7 (YUM)

Installationsumgebung: CentOS7 64-Bit, MySQL5.7 1...

Vue realisiert den Prozentbalkeneffekt

In diesem Artikel wird der spezifische Code von V...

Installieren Sie MySQL 5.6 aus der Yum-Quelle im Centos7.4-System

Systemumgebung: centos7.4 1. Prüfen Sie, ob die D...

Anwendungsbeispiele für React Hooks

Inhaltsverzeichnis Ein einfaches Komponentenbeisp...

Detaillierte Erklärung zur sauberen Deinstallation von Docker

Zunächst die Informationen zur Serverumgebung: Gr...

React-Tipps zeigen Ihnen, wie Sie Probleme mit Hook-Abhängigkeiten beseitigen

Ein sehr häufiges Szenario in react -Projekten: c...

Details zum Überschreiben von Prototypmethoden in JavaScript-Instanzobjekten

Inhaltsverzeichnis In JavaScript können wir norma...

Mehrere Navigationsrichtungen, die in Zukunft beliebt sein werden

<br />Dies ist nicht nur ein Zeitalter der I...

MySQL-Triggerprinzip und Analyse von Anwendungsbeispielen

Dieser Artikel erläutert anhand von Beispielen di...

WeChat-Applet implementiert Formularüberprüfung

Validierung des WeChat-Applets-Formulars. Zu Ihre...