最近在作原生項目集成RN的時候遇到了一個問題:若是從原生進入RN有多個入口或者說從原生不一樣的地方能夠進入到不一樣的RN組件,該怎麼作?由此展開了調研。
在調研後得出了兩種方案:javascript
註冊多個根組件入口java
只註冊一個入口,根據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
這種方式是在進入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
打開第一個RN頁面,內存會明顯拔高,而且隨時間會緩慢增長,然後在一段時間後會明顯下降並又開始緩慢增長,如此循環。
在退出這個RN頁面後內存佔用並無明顯降低
在打開第二個頁面以後頁面會有個明顯降低然後又迅速增多(以下圖V字形曲線)
退出第二個RN頁面再打開第三個RN頁面,內存佔用會較明顯降低然後又迅速增多(以下圖V字形曲線)
最高內存佔用在4M左右。
未加載jsbundle以前:
加載第一個RN頁面,內存佔用曲線明顯拔高,而且隨時間逐漸增多,但在一段時間後會跌落,如此循環
退出RN頁面,內存佔用沒有明顯減小
加載第二個RN頁面,加載後增長,事後會減小,退出RN頁面內存佔用沒有明顯減小
加載第三個RN頁面,加載後增長,事後會減小,退出RN頁面內存佔用沒有明顯減小。APP最高佔用內存也在4M左右
整體來講:單註冊入口和多註冊入口,佔用內存沒有明顯區別