React Native多入口實現

前言

最近在作原生項目集成RN的時候遇到了一個問題:若是從原生進入RN有多個入口或者說從原生不一樣的地方能夠進入到不一樣的RN組件,該怎麼作?由此展開了調研。
在調研後得出了兩種方案:javascript

  1. 註冊多個根組件入口java

  2. 只註冊一個入口,根據RN傳遞屬性選擇進入不一樣的組件react

註冊多個根組件入口

這種方案是在index.android.js /index.ios.js 中註冊多個跟組件。
下面以android爲例。
Android項目集成RN此處不具體展開,請參考:
React Native植入原生Android應用的流程解析
彈射起步:Android原生項目集成React Native模塊android

多註冊根組件方式以下:ios

'use strict'
import {
  AppRegistry,
} from 'react-native';
import RNEntrance1 from './js/RNEntrance1'
import RNEntrance2 from './js/RNEntrance2'
import RNEntrance3 from './js/RNEntrance3'

AppRegistry.registerComponent('RNActivity1', () => RNEntrance1);
AppRegistry.registerComponent('RNActivity2', () => RNEntrance2);
AppRegistry.registerComponent('RNActivity3', () => RNEntrance3);

相應的,在Android原生模塊中須要創建多個對應的ReactActivity,並在getMainComponentName方法中返回對應的跟組件名字,以下圖:react-native

enter description here

只註冊一個入口,根據RN傳遞屬性選擇進入不一樣的組件

這種方式是在進入RN以前設置傳遞屬性,而後在根組件獲取這個屬性,並跟進屬性的不一樣進入到不一樣的入口。ide

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

    @Override
    protected ReactActivityDelegate createReactActivityDelegate() {
        return new ReactActivityDelegate(this, getMainComponentName()) {
            @Nullable
            @Override
            protected Bundle getLaunchOptions() {
                return MainApplication.getBundle();
            }
        };
    }
}

getLaunchOptions方法能夠設置傳遞給跟組件的屬性值(Bundle類型),此處以傳遞int值爲例。
具體的MainApplication.java 代碼以下:測試

public class MainApplication extends Application implements ReactApplication {

    public final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {

        @Override
        public boolean getUseDeveloperSupport() {
            return BuildConfig.DEBUG;
        }

        @Override
        protected List<ReactPackage> getPackages() {
            return Arrays.<ReactPackage>asList(
                    new MainReactPackage()
            );
        }
    };

    @Override
    public ReactNativeHost getReactNativeHost() {
        return mReactNativeHost;
    }

    private static Bundle sBundle = new Bundle();
    public static int RN_ENTRANCE_1 = 1;
    public static int RN_ENTRANCE_2 = 2;
    public static int RN_ENTRANCE_3 = 3;

    public static void setRNInitProps(int entrance) {
        sBundle.putInt("entrance",entrance);
    }

    public static Bundle getBundle(){
        return sBundle;
    }
}

而在index.android.js 中獲取this.props.entrance並判斷不一樣條件下進入不一樣的RN頁面ui

import React, {Component} from 'react';
import {AppRegistry,} from 'react-native';
import RNEntrance1 from './js/RNEntrance1'
import RNEntrance2 from './js/RNEntrance2'
import RNEntrance3 from './js/RNEntrance3'

class Root extends Component {
    render() {
        switch (this.props.entrance) {
            case 1:
                return <RNEntrance1 />
            case 2:
                return <RNEntrance2 />
            case 3:
                return <RNEntrance3 />
        }

    }
}
AppRegistry.registerComponent('RNActivity', () => Root);

兩種方式對比

註冊多個根組件方式

第一種方案在網上聽說內存開銷太大,所以針對二者進行內存測試。
剛打開APP內存佔用如圖:this

enter description here

打開第一個RN頁面,內存會明顯拔高,而且隨時間會緩慢增長,然後在一段時間後會明顯下降並又開始緩慢增長,如此循環。

enter description here

在退出這個RN頁面後內存佔用並無明顯降低
在打開第二個頁面以後頁面會有個明顯降低然後又迅速增多(以下圖V字形曲線)

enter description here

退出第二個RN頁面再打開第三個RN頁面,內存佔用會較明顯降低然後又迅速增多(以下圖V字形曲線)

enter description here

最高內存佔用在4M左右。

單註冊入口的屬性選擇方式

未加載jsbundle以前:

enter description here
加載第一個RN頁面,內存佔用曲線明顯拔高,而且隨時間逐漸增多,但在一段時間後會跌落,如此循環

enter description here
退出RN頁面,內存佔用沒有明顯減小
加載第二個RN頁面,加載後增長,事後會減小,退出RN頁面內存佔用沒有明顯減小

enter description here
加載第三個RN頁面,加載後增長,事後會減小,退出RN頁面內存佔用沒有明顯減小。APP最高佔用內存也在4M左右

enter description here

整體來講:單註冊入口和多註冊入口,佔用內存沒有明顯區別

相關文章
相關標籤/搜索