ReactNative预加载解决方案
第一步、实现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.创建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);
}
/**
* 从当前界面移除 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());
}
}
}
第二步、预加载ReactRootView
public class XNApplication extends BaseApplication implements ReactApplication {
@Override
public void onCreate() {
... ...
XNReactNativePreLoader.preLoad(this, RnActivity.MAIN_COMPONENT_NAME);
}
}
第三步、实现自已的ReactActivityDelegate
public class XNReactActivityDelegate extends ReactActivityDelegate{
//把ReactActivityDelegate中的所有源码拷备过来
//有些成员属性根据自已的实际情况进行修改,下面只讲重点
protected void loadApp(String appKey) {
if (mReactRootView != null) {
throw new IllegalStateException("Cannot loadApp while app is already running.");
}
//这里生成的RootView从我们预加载的缓存中获取; 这里是重点.
mReactRootView = XNReactNativePreLoader.getReactRootView(appKey);
if(mReactRootView == null) {
mReactRootView = createRootView();
mReactRootView.startReactApplication(
getReactNativeHost().getReactInstanceManager(),
appKey,
getLaunchOptions());
}
getPlainActivity().setContentView(mReactRootView);
}
}
第四步、在ReactMainActivity中重写如下方法
public class ReactMainActivity extends ReactActivity {
@Override
protected ReactActivityDelegate createReactActivityDelegate() {
//这里用我们自已的Delegate
return new XNReactActivityDelegate(this,getMainComponentName());
}
}
预加载JSBundle和初始化RootView会造成项目中不能使用Modal组件,因为初始化RootView传进去的参数上下文Context是一个Application,这个上下文是不能弹对话框的. 而Modal是基于Dialog的一个实现;