欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

React Native 啟動(dòng)流程詳細(xì)解析

 更新時(shí)間:2021年08月17日 11:55:48   作者:大閑人三石兄  
這篇文章主要介紹了React Native 啟動(dòng)流程簡析,文以 react-native-cli 創(chuàng)建的示例工程(安卓部分)為例,給大家分析 React Native 的啟動(dòng)流程,需要的朋友可以參考下

導(dǎo)讀:本文以 react-native-cli 創(chuàng)建的示例工程(安卓部分)為例,分析 React Native 的啟動(dòng)流程。

工程創(chuàng)建步驟可以參考官網(wǎng)。本文所分析 React Native 版本為 v0.64.2。

我們知道上述工程是一個(gè)安卓應(yīng)用,打開 android/ 目錄下源碼文件,首先發(fā)現(xiàn)它創(chuàng)建了兩個(gè) java 文件:MainApplication.javaMainActivity.java,分別做了應(yīng)用以及主 Activity 的定義。

安卓應(yīng)用的啟動(dòng)流程是:在啟動(dòng)第一個(gè) activity 之前會(huì)創(chuàng)建一個(gè)全局唯一的 Application 對(duì)象。故在此我們先分析 MainApplication

MainApplication

public class MainApplication extends Application implements ReactApplication {
  private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
    @Override
        public boolean getUseDeveloperSupport() {
          return BuildConfig.DEBUG;
        }
        @Override
        protected List<ReactPackage> getPackages() {
          @SuppressWarnings("UnnecessaryLocalVariable")
          List<ReactPackage> packages = new PackageList(this).getPackages();
          // 其它對(duì) packages 的操作
          return packages;
        }
        @Override
        protected String getJSMainModuleName() {
          return "index";
        }
  }
  @Override
  public ReactNativeHost getReactNativeHost() {
    return mReactNativeHost;
  }
  @Override
  public void onCreate() {
    super.onCreate();
    SoLoader.init(this, /* native exopackage */ false);
    initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
  }

MainApplication 繼承自 Application 類,并且實(shí)現(xiàn)了 ReactApplication 接口。在其中做的事情有:

1.創(chuàng)建成員變量 ReactNativeHost 的實(shí)例,并在創(chuàng)建過程中通過重寫 ReactNativeHost 類方法的方式,注入一些配置,包括:

  1. getUseDeveloperSupport: 配置是否開啟調(diào)試
  2. getPackages: 配置要加載的模塊
  3. getJSMainModuleName: 配置 js 模塊的入口文件名

2.在 onCreate 中:

  1. 調(diào)用 Soloader 庫。Soloader 是 facebook 推出的一個(gè) so 文件加載庫,它能夠處理 so 文件的依賴在 react-native 中,所有框架相關(guān)的 so 文件都是通過SoLoader完成加載的
  2. 通過 ReactInstanceManager 初始化 Flipper。Flipper 是 facebook 推出的用于 debug ios、Android、React Native 應(yīng)用的工具。

在這里簡要介紹下 ReactNativeHostReactInstanceManager

ReactNativeHost

ReactNativeHost 是個(gè)抽象類,開發(fā)者可以重寫其中的方法,其主要的作用是:在 application 中指定一些賦值操作,進(jìn)而獲取 ReactInstanceManager 的實(shí)例。所以可以把 ReactNativeHost 作為將用戶自定義的參數(shù)賦值到 ReactInstanceManager 實(shí)例的中轉(zhuǎn)站。核心方法是: getReactInstanceManager,詳細(xì)分析見下文。

ReactInstanceManager

該類為核心類,主要負(fù)責(zé)管理 JS 的加載、維護(hù)生命周期、管理 JS 與 C++ 的交互等等??梢园?ReactInstanceManager 理解成 JS 與 C++ 的中轉(zhuǎn)橋梁。

MainActivity

接著看 MainActivity.java

public class MainActivity extends ReactActivity {
  @Override
  protected String getMainComponentName() {
    return "myProject";
  }
}

MainActivity 類中僅重寫了 getMainComponentName 方法。該類繼承自 ReactActivity,我們?cè)賮砜雌?ReactActivity。

public abstract class ReactActivity extends AppCompatActivity
    implements DefaultHardwareBackBtnHandler, PermissionAwareActivity {
  private final ReactActivityDelegate mDelegate;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mDelegate.onCreate(savedInstanceState);
  }

ReactActivity 全權(quán)委托給 ReactActivityDelegate 來處理 onCreate 生命周期。來看 ReactActivityDelegateonCreate。

protected void onCreate(Bundle savedInstanceState) {
  String mainComponentName = getMainComponentName();
  mReactDelegate =
      new ReactDelegate(
          getPlainActivity(), getReactNativeHost(), mainComponentName, getLaunchOptions()) {
        @Override
        protected ReactRootView createRootView() {
          return ReactActivityDelegate.this.createRootView();
        }
      };
    if (mMainComponentName != null) {
      loadApp(mainComponentName);
    }
  }

這里首先創(chuàng)建了 ReactDelegate 實(shí)例。接著來看 loadApp 方法:

protected void loadApp(String appKey) {
  mReactDelegate.loadApp(appKey);
  getPlainActivity().setContentView(mReactDelegate.getReactRootView());
}

由此走到 ReactDelegate 實(shí)例的 loadApp 方法:

public void loadApp(String appKey) {
  if (mReactRootView != null) {
    throw new IllegalStateException("Cannot loadApp while app is already running.");
  }
  mReactRootView = createRootView();
  mReactRootView.startReactApplication(
      getReactNativeHost().getReactInstanceManager(), appKey, mLaunchOptions);
}

在這里做了三件事:創(chuàng)建 rootView (createRootView)、創(chuàng)建 ReactInstanceManager (getReactInstanceManager)、創(chuàng)建 ReactApplication (startReactApplication)。

createRootView

首先看下什么是 rootView。

public class ReactRootView extends FrameLayout implements RootView, ReactRoot { /* ... */}

ReactRootView 繼承自 FrameLayout,并且實(shí)現(xiàn)了 RootView、ReactRoot 兩個(gè)接口。FrameLayout 是安卓幾大布局中較為簡單的一個(gè),整個(gè)界面被當(dāng)成一塊空白備用區(qū)域,所有元素以左上角對(duì)齊堆疊。ReactRootView 繼承自 FrameLayout,表明其也是作為簡單布局而存在,UI 的繪制渲染都發(fā)生在上面。

getReactInstanceManager

ReactInstanceManager 是一個(gè)核心類,管理著 JS 的加載、C++ 和 JS 的交互、初始化參數(shù)等。最終調(diào)用來到 ReactNativeHost 類中的 createReactInstanceManager 方法:

protected ReactInstanceManager createReactInstanceManager() {
  ReactInstanceManagerBuilder builder = /* ... */

  for (ReactPackage reactPackage : getPackages()) {
    builder.addPackage(reactPackage);
  }

  String jsBundleFile = getJSBundleFile();
  if (jsBundleFile != null) {
    builder.setJSBundleFile(jsBundleFile);
  } else {
    builder.setBundleAssetName(Assertions.assertNotNull(getBundleAssetName()));
  }
  
  ReactInstanceManager reactInstanceManager = builder.build();
  return reactInstanceManager;
}

此處做的事情如下:

  • 創(chuàng)建 ReactInstanceManagerBuilder 實(shí)例。這里采用建造者模式來構(gòu)造 ReactInstanceManager 實(shí)例,故在此先傳入?yún)?shù)設(shè)定構(gòu)造者;
  • 把在 ReactNativeHost 中注冊(cè)的 packages 都添加到 ReactInstanceManagerBuilder 實(shí)例中;
  • 如果 getJSBundleFile 不為空,則加載對(duì)應(yīng)的文件,否則加載默認(rèn)的 jsBundleFile;
  • 調(diào)用 builder.build 方法。通過建造者真正構(gòu)造 ReactInstanceManager 實(shí)例

startReactApplication

  public void startReactApplication(/* */) {
    // ...
    try {
      // ...
      mReactInstanceManager.createReactContextInBackground();
    } finally {
      // ...
    }
  }

最終執(zhí)行到 ReactInstanceManagercreateReactContextInBackground 方法中。最后經(jīng)過調(diào)用鏈:recreateReactContextInBackgroundInner() -> recreateReactContextInBackgroundFromBundleLoader() -> recreateReactContextInBackground() -> runCreateReactContextOnNewThread()

runCreateReactContextOnNewThread 主要做了兩件事:

  1. 創(chuàng)建一個(gè)新的線程,并在新線程中通過 createReactContext 創(chuàng)建 ReactContext 上下文;
  2. 通過 setupReactContext 來設(shè)置上下文環(huán)境,并最終調(diào)用到 AppRegistry.js 啟動(dòng)App。

詳細(xì)分析我們放到另一篇文章:React Native startReactApplication 流程梳理

總結(jié)

總結(jié)本文,通過 react-native-cli 創(chuàng)建的示例工程(安卓部分)為例,順著兩個(gè)類 MainApplicationMainActivity 的執(zhí)行流程,抓住主干邏輯,最終梳理出了 React Native 從開始啟動(dòng)至執(zhí)行用戶 js 文件的過程??梢钥吹剑?/p>

MainApplication 的作用主要是傳入用戶的配置,并做 so 庫以及應(yīng)用 debug 工具的初始化工作;

MainActivity 的作用主要是:

  1. 為應(yīng)用創(chuàng)建 rootView 布局容器;
  2. 創(chuàng)建 ReactInstanceManager 核心類,用于后續(xù)管理 JS 的加載、C++ 和 JS 的交互、初始化參數(shù)等;
  3. 通過 startReactApplication 來創(chuàng)建 ReactContext 上下文,并最終調(diào)用到 AppRegistry.js 啟動(dòng)App。

到此這篇關(guān)于React Native 啟動(dòng)流程簡析的文章就介紹到這了,更多相關(guān)React Native 啟動(dòng)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • React?Native采用Hermes熱更新打包方案詳解

    React?Native采用Hermes熱更新打包方案詳解

    這篇文章主要介紹了React?Native采用Hermes熱更新打包實(shí)戰(zhàn),在傳統(tǒng)的熱更新方案中,我們實(shí)現(xiàn)熱更新需要借助code-push開源方案,包括熱更新包的發(fā)布兩種方式詳解,感興趣的朋友一起看看吧
    2022-05-05
  • React編程中需要注意的兩個(gè)錯(cuò)誤

    React編程中需要注意的兩個(gè)錯(cuò)誤

    React可以說是前端的先驅(qū)者,它總是會(huì)引領(lǐng)整個(gè)前端的潮流。 但我們?cè)谑褂靡步?jīng)常會(huì)遇到錯(cuò)誤,下面這篇文章主要給大家介紹了關(guān)于React編程中需要注意的兩個(gè)錯(cuò)誤,需要的朋友可以參考下
    2021-05-05
  • React中閉包陷阱的幾種情及解決方案

    React中閉包陷阱的幾種情及解決方案

    在react中我們使用其提供的Hooks中的useState,useEffect,useCallback 時(shí),可能會(huì)造成閉包陷阱,下面我們來看一下出現(xiàn)的情況以及如何解決,感興趣的小伙伴跟著小編一起來看看吧
    2024-07-07
  • React Ant Design樹形表格的復(fù)雜增刪改操作

    React Ant Design樹形表格的復(fù)雜增刪改操作

    這篇文章主要介紹了React Ant Design樹形表格的復(fù)雜增刪改操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • React中的Context應(yīng)用場(chǎng)景分析

    React中的Context應(yīng)用場(chǎng)景分析

    這篇文章主要介紹了React中的Context應(yīng)用場(chǎng)景分析,Context 提供了一種在組件之間共享數(shù)據(jù)的方式,而不必顯式地通過組件樹的逐層傳遞 props,通過實(shí)例代碼給大家介紹使用步驟,感興趣的朋友跟隨小編一起看看吧
    2021-06-06
  • react中JSX的注意點(diǎn)詳解

    react中JSX的注意點(diǎn)詳解

    這篇文章主要為大家詳細(xì)介紹了react中JSX的注意點(diǎn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • React中組件優(yōu)化的最佳方案分享

    React中組件優(yōu)化的最佳方案分享

    React組件性能優(yōu)化可以減少渲染真實(shí)DOM的頻率,以及減少VD比對(duì)的頻率,本文為大家整理了一些有效的React組件優(yōu)化方法,需要的小伙伴可以參考下
    2023-12-12
  • react中如何使用定義數(shù)據(jù)并監(jiān)聽其值

    react中如何使用定義數(shù)據(jù)并監(jiān)聽其值

    這篇文章主要介紹了react中如何使用定義數(shù)據(jù)并監(jiān)聽其值問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • React antd tabs切換造成子組件重復(fù)刷新

    React antd tabs切換造成子組件重復(fù)刷新

    這篇文章主要介紹了React antd tabs切換造成子組件重復(fù)刷新,需要的朋友可以參考下
    2021-04-04
  • react native帶索引的城市列表組件的實(shí)例代碼

    react native帶索引的城市列表組件的實(shí)例代碼

    本篇文章主要介紹了react-native城市列表組件的實(shí)例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-08-08

最新評(píng)論