ReactNative預(yù)加載解決方案
第一步炕贵、實(shí)現(xiàn)ReactRootView緩存功能
源碼如下:
public class XNReactNativePreLoader {
private static final Map<String,ReactRootView> S_REACT_ROOT_VIEW_CACHE = new HashMap<>();
/**
* 初始化ReactRootView,并添加到緩存
* @param activity
* @param componentName
*/
public static void preLoad(ReactApplication activity, String componentName) {
if (S_REACT_ROOT_VIEW_CACHE.get(componentName) != null) {
return;
}
// 1.創(chuàng)建ReactRootView
ReactRootView rootView = new ReactRootView((Context)activity);
rootView.startReactApplication(
activity.getReactNativeHost().getReactInstanceManager(),
componentName,
new XNReactActivityDelegate((Context)activity,null).getLaunchOptions());
// 2.添加到緩存
S_REACT_ROOT_VIEW_CACHE.put(componentName, rootView);
}
/**
* 獲取ReactRootView
* @param componentName
* @return
*/
public static ReactRootView getReactRootView(String componentName) {
return S_REACT_ROOT_VIEW_CACHE.get(componentName);
}
/**
* 從當(dāng)前界面移除 ReactRootView
* @param component
*/
public static void release(String component) {
try {
ReactRootView rootView = getReactRootView(component);
ViewGroup parent = (ViewGroup) rootView.getParent();
if (parent != null) {
parent.removeView(rootView);
}
} catch (Throwable e) {
Log.e("XNReactNativePreLoader",e.getMessage());
}
}
}
第二步悲靴、預(yù)加載ReactRootView
public class XNApplication extends BaseApplication implements ReactApplication {
@Override
public void onCreate() {
... ...
XNReactNativePreLoader.preLoad(this, RnActivity.MAIN_COMPONENT_NAME);
}
}
第三步惜颇、實(shí)現(xiàn)自已的ReactActivityDelegate
public class XNReactActivityDelegate extends ReactActivityDelegate{
//把ReactActivityDelegate中的所有源碼拷備過(guò)來(lái)
//有些成員屬性根據(jù)自已的實(shí)際情況進(jìn)行修改督禽,下面只講重點(diǎn)
protected void loadApp(String appKey) {
if (mReactRootView != null) {
throw new IllegalStateException("Cannot loadApp while app is already running.");
}
//這里生成的RootView從我們預(yù)加載的緩存中獲取; 這里是重點(diǎn).
mReactRootView = XNReactNativePreLoader.getReactRootView(appKey);
if(mReactRootView == null) {
mReactRootView = createRootView();
mReactRootView.startReactApplication(
getReactNativeHost().getReactInstanceManager(),
appKey,
getLaunchOptions());
}
getPlainActivity().setContentView(mReactRootView);
}
}
第四步总处、在ReactMainActivity中重寫(xiě)如下方法
public class ReactMainActivity extends ReactActivity {
@Override
protected ReactActivityDelegate createReactActivityDelegate() {
//這里用我們自已的Delegate
return new XNReactActivityDelegate(this,getMainComponentName());
}
}
預(yù)加載JSBundle和初始化RootView會(huì)造成項(xiàng)目中不能使用Modal組件,因?yàn)槌跏蓟疪ootView傳進(jìn)去的參數(shù)上下文Context是一個(gè)Application鹦马,這個(gè)上下文是不能彈對(duì)話框的. 而Modal是基于Dialog的一個(gè)實(shí)現(xiàn);