Detaillierte Analyse des React Native-Startvorgangs

Detaillierte Analyse des React Native-Startvorgangs

Einführung: Dieser Artikel verwendet das von react-native-cli erstellte Beispielprojekt (Android-Teil) als Beispiel, um den Startvorgang von React Native zu analysieren.

Die Schritte zur Projekterstellung finden Sie auf der offiziellen Website. Die in diesem Artikel analysierte React Native Version ist v0.64.2 .

Wir wissen, dass das obige Projekt eine Android-Anwendung ist. Öffnen Sie die Quellcodedatei im Verzeichnis android/ und Sie werden zunächst feststellen, dass zwei Java-Dateien erstellt werden: MainApplication.java und MainActivity.java , die jeweils die Anwendung und die Hauptaktivität definieren.

Der Startvorgang einer Android-Anwendung läuft wie folgt ab: Vor dem Start der ersten activity wird ein global eindeutiges Application erstellt. Hier analysieren wir also zuerst MainApplication

Hauptanwendung

öffentliche Klasse MainApplication erweitert Application implementiert ReactApplication {
  private final ReactNativeHost mReactNativeHost = neuer ReactNativeHost(dieser) {
    @Überschreiben
        öffentliches Boolean getUseDeveloperSupport() {
          BuildConfig.DEBUG zurückgeben;
        }
        @Überschreiben
        geschützte Liste<ReactPackage> getPackages() {
          @SuppressWarnings("UnnötigeLokaleVariable")
          Liste<ReactPackage>-Pakete = neue PackageList(this).getPackages();
          // Andere Operationen an Paketen geben Pakete zurück;
        }
        @Überschreiben
        geschützter String getJSMainModuleName() {
          gib "Index" zurück;
        }
  }
  @Überschreiben
  öffentliche ReactNativeHost getReactNativeHost() {
    gibt mReactNativeHost zurück;
  }
  @Überschreiben
  öffentliche void beiErstellen() {
    super.onCreate();
    SoLoader.init(dieses, /* natives Exopaket */ false);
    initializeFlipper(dies, getReactNativeHost().getReactInstanceManager());
  }

MainApplication erbt von der Application-Klasse und implementiert ReactApplication Schnittstelle. Zu den Aufgaben gehören:

1. Erstellen Sie eine Instanz der Mitgliedsvariable ReactNativeHost und fügen Sie einige Konfigurationen ein, indem Sie während des Erstellungsprozesses die Klassenmethode ReactNativeHost überschreiben, darunter:

  1. getUseDeveloperSupport: Konfigurieren Sie, ob das Debuggen aktiviert werden soll
  2. getPackages: Konfigurieren Sie die zu ladenden Module
  3. getJSMainModuleName: Konfigurieren Sie den Eintragsdateinamen des JS-Moduls

2. In onCreate:

  1. Rufen Sie die Soloader-Bibliothek an. Soloader ist eine von Facebook gestartete Bibliothek zum Laden von SO-Dateien. Sie kann die Abhängigkeit von SO-Dateien verarbeiten. In React-Native werden alle Framework-bezogenen SO-Dateien über SoLoader geladen.
  2. Initialisieren Sie Flipper über ReactInstanceManager . Flipper ist ein von Facebook eingeführtes Tool zum Debuggen von iOS-, Android- und React Native-Anwendungen.

Hier ist eine kurze Einführung in ReactNativeHost und ReactInstanceManager

ReactNativeHost

ReactNativeHost ist eine abstrakte Klasse und Entwickler können ihre Methoden überschreiben. Ihre Hauptfunktion besteht darin, einige Zuweisungsoperationen in der Anwendung anzugeben und dann eine Instanz von ReactInstanceManager abzurufen. Daher kann ReactNativeHost als Transitstation zum Zuweisen benutzerdefinierter Parameter zu ReactInstanceManager Instanzen verwendet werden. Die Kernmethode ist: getReactInstanceManager , siehe unten für eine detaillierte Analyse.

ReactInstanceManager

Diese Klasse ist die Kernklasse, die hauptsächlich für die Verwaltung des JS-Ladens, die Aufrechterhaltung des Lebenszyklus, die Verwaltung der Interaktion zwischen JS und C++ usw. verantwortlich ist. ReactInstanceManager kann als Übertragungsbrücke zwischen JS und C++ verstanden werden.

Hauptaktivität

Schauen Sie sich als nächstes MainActivity.java an:

öffentliche Klasse MainActivity erweitert ReactActivity {
  @Überschreiben
  geschützter String getMainComponentName() {
    returniere "meinProjekt";
  }
}

Nur die Methode getMainComponentName wird in MainActivity Klasse überschrieben. Diese Klasse erbt von ReactActivity . Schauen wir uns deren ReactActivity an.

öffentliche abstrakte Klasse ReactActivity erweitert AppCompatActivity
    implementiert DefaultHardwareBackBtnHandler, PermissionAwareActivity {
  privates endgültiges ReactActivityDelegate mDelegate;
  @Überschreiben
  geschützt void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mDelegate.onCreate(savedInstanceState);
  }

ReactActivity delegiert die Handhabung onCreate Lebenszyklus vollständig an ReactActivityDelegate . Schauen wir uns onCreate von ReactActivityDelegate an.

geschützt void onCreate(Bundle savedInstanceState) {
  Zeichenfolge mainComponentName = getMainComponentName();
  mReactDelegate =
      neuer ReactDelegate(
          getPlainActivity(), getReactNativeHost(), mainComponentName, getLaunchOptions()) {
        @Überschreiben
        geschützte ReactRootView createRootView() {
          gibt ReactActivityDelegate.this.createRootView() zurück;
        }
      };
    if (mMainComponentName != null) {
      loadApp(Hauptkomponentenname);
    }
  }

Hier wird zuerst die ReactDelegate-Instanz erstellt. Schauen wir uns als nächstes loadApp an:

geschützt void loadApp(String appKey) {
  mReactDelegate.loadApp(appKey);
  getPlainActivity().setContentView(mReactDelegate.getReactRootView());
}

Von hier aus gehen wir zur loadApp -Methode der ReactDelegate -Instanz:

öffentliche void loadApp(String appKey) {
  wenn (mReactRootView != null) {
    throw new IllegalStateException("App kann nicht geladen werden, solange die App bereits ausgeführt wird.");
  }
  : mReactRootView = createRootView();
  mReactRootView.startReactApplication(
      getReactNativeHost().getReactInstanceManager(), appKey, mLaunchOptions);
}

Hier werden drei Dinge erledigt: RootView erstellen ( createRootView ), ReactInstanceManager erstellen ( getReactInstanceManager ) und ReactApplication erstellen ( startReactApplication ).

Stammansicht erstellen

Sehen wir uns zunächst an, was RootView ist.

öffentliche Klasse ReactRootView erweitert FrameLayout implementiert RootView, ReactRoot { /* ... */}

ReactRootView erbt von FrameLayout und implementiert RootView und ReactRoot . FrameLayout ist eines der einfacheren Layouts in Android. Die gesamte Benutzeroberfläche wird als leerer Reservebereich behandelt und alle Elemente werden mit der oberen linken Ecke ausgerichtet gestapelt. ReactRootView erbt von FrameLayout , was bedeutet, dass es auch als einfaches Layout existiert und UI 的繪制渲染darauf erfolgt.

getReactInstanceManager

ReactInstanceManager ist eine Kernklasse, die das Laden von JS, die Interaktion zwischen C++ und JS, Initialisierungsparameter usw. verwaltet. Schließlich erfolgt der Aufruf createReactInstanceManager in ReactNativeHost :

geschützter ReactInstanceManager createReactInstanceManager() {
  ReactInstanceManagerBuilder-Builder = /* ... */

  für (ReactPackage reactPackage : getPackages()) {
    : Erstellen Sie ein Paket mit einer bestimmten Anzahl von Paketen.
  }

  : String jsBundleFile = getJSBundleFile();
  if (jsBundleFile != null) {
    builder.setJSBundleFile(jsBundleFile);
  } anders {
    builder.setBundleAssetName(Assertions.assertNotNull(getBundleAssetName()));
  }
  
  ReactInstanceManager reactInstanceManager = builder.build();
  reactInstanceManager zurückgeben;
}

Folgendes ist passiert:

  • Erstellen Sie ReactInstanceManagerBuilder Instanz. Das Builder-Muster wird hier verwendet, um die ReactInstanceManager -Instanz zu erstellen, daher werden die Parameter übergeben, um zuerst den Konstruktor festzulegen.
  • Fügen Sie alle in ReactNativeHost registrierten packages zur ReactInstanceManagerBuilder -Instanz hinzu;
  • Wenn getJSBundleFile nicht leer ist, laden Sie die entsprechende Datei, andernfalls laden Sie das Standard jsBundleFile .
  • Rufen Sie builder.build auf. Konstruieren Sie ReactInstanceManager Instanz tatsächlich mit dem Builder

Starten Sie die ReactApplication

  öffentliche void startReactApplication(/* */) {
    // ...
    versuchen {
      // ...
      mReactInstanceManager.createReactContextInBackground();
    Endlich
      // ...
    }
  }

Abschließend erfolgt die Ausführung in der Methode createReactContextInBackground von ReactInstanceManager . Schließlich lautet die Aufrufkette: recreateReactContextInBackgroundInner() -> recreateReactContextInBackgroundFromBundleLoader() -> recreateReactContextInBackground() -> runCreateReactContextOnNewThread()

runCreateReactContextOnNewThread macht hauptsächlich zwei Dinge:

  1. Erstellen Sie einen neuen Thread und erstellen Sie über createReactContext ReactContext -Kontext im neuen Thread.
  2. Die Kontextumgebung wird über setupReactContext eingerichtet und schließlich wird AppRegistry.js aufgerufen, um die App zu starten.

Wir werden die detaillierte Analyse in einem anderen Artikel veröffentlichen: Analyse des React Native startReactApplication-Prozesses.

Zusammenfassen

Um diesen Artikel zusammenzufassen: Wir nehmen das von react-native-cli erstellte Beispielprojekt (Android-Teil) als Beispiel, folgen dem Ausführungsfluss der beiden Klassen MainApplication und MainActivity , erfassen die Hauptlogik und klären schließlich den Prozess von React Native vom Start bis zur Ausführung der Benutzer js Dateien. Sie können sehen:

Die Hauptfunktion von MainApplication besteht darin, die Benutzerkonfiguration zu übergeben und die so Bibliothek und die Anwendungs- debug -Tools zu initialisieren.

Die Hauptfunktionen von MainActivity sind:

  1. Erstellen Sie einen rootView -Layoutcontainer für die Anwendung.
  2. Erstellen Sie ReactInstanceManager Kernklasse, um das JS-Laden, die C++- und JS-Interaktion, Initialisierungsparameter usw. zu verwalten.
  3. ReactContext -Kontext wird über startReactApplication erstellt und schließlich wird AppRegistry.js aufgerufen, um die App zu starten.

Dies ist das Ende dieses Artikels über die kurze Analyse des Startvorgangs von React Native. Weitere relevante Inhalte zum Start von React Native finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird!

Das könnte Sie auch interessieren:
  • Reagieren Sie auf den nativen ScrollView-Pulldown-Aktualisierungseffekt
  • Eine kurze Analyse der startReactApplication-Methode von React Native
  • Tiefgreifendes Verständnis des benutzerdefinierten Routing-Managements von React Native
  • So verwenden Sie Lottie-Animationen in React Native-Projekten

<<:  Analyse des Prinzips und der Erstellungsmethode der temporären MySQL-Tabelle

>>:  Lösung für das Problem des IP-Verlusts durch das Kopieren der virtuellen Centos8-Maschine unter VMWARE

Artikel empfehlen

So ändern Sie den iTunes-Sicherungspfad unter Windows

0. Vorbereitung: • Schließen Sie iTunes • Beenden...

So entfernen Sie „Enter“, „Senden“ und „Enter != Senden“ aus dem Formular

Um das Problem „Eingeben != Absenden“ zu implement...

So bereinigen Sie den von Docker belegten Speicherplatz

Docker nimmt viel Platz ein. Immer wenn wir Conta...

js implementiert eine auf Canvas basierende Uhrkomponente

Canvas war schon immer ein unverzichtbares Tag-El...

MySQL 8.0.20 Installations- und Konfigurations-Tutorial unter Win10

Super ausführliches Tutorial zur Installation und...

So verwenden Sie das Modul-FS-Dateisystem in Nodejs

Inhaltsverzeichnis Überblick Dateideskriptoren Sy...

MySQL-Datenbank-Indexreihenfolge durch Sortierung – detaillierte Erklärung

Inhaltsverzeichnis Die Ursache des Vorfalls Sorti...

CSS3 erzielt einen unendlichen Scroll-/Karusselleffekt der Liste

Effektvorschau Ideen Scrollen Sie durch die aktue...

Detailliertes Tutorial zur Installation von Docker auf CentOS 8.4

Inhaltsverzeichnis Vorwort: Systemanforderungen: ...