版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhang___yong/article/details/82839553
在使用ReactInstanceManager.Builder构建一个ReactInstanceManager实例的时候只能传入一个bundle,setBundleAssetName和setJSBundleFile分别对应从assets和从一个文件路径加载Bundle。有时需要将业务代码和通用代码分离,也就是分成两个bundle,这时候加载第二个Bundle就要借助反射了。
ReactContext mReactContext = manager.getCurrentReactContext();
final Runnable loadRN = new Runnable() {
@Override
public void run() {
mReactRootView.startReactApplication(manager, "HomeScene", getLaunchOptions());
if (BuildConfig.DEBUG_PANEL_ENTRANCE) {
setContentView(wrapReactRootViewWithDebugButton(mReactRootView));
} else {
setContentView(mReactRootView);
}
}
};
if (mReactContext == null) {
manager.addReactInstanceEventListener(new ReactInstanceManager.ReactInstanceEventListener() {
@Override
public void onReactContextInitialized(ReactContext context) {
ReactUtils.loadBusinessScript(context);
loadRN.run();
}
});
manager.createReactContextInBackground();
} else {
ReactUtils.loadBusinessScript(mReactContext);
loadRN.run();
}
因为加载第二个的过程是放在回调接口里异步执行的,所以要把startReactApplication和setContentView放在加载后面,否则没加载完就执行会报错。加载过程:
public static void loadBusinessScript(ReactContext context) {
CatalystInstance instance = context.getCatalystInstance();
// try {
// Method method = CatalystInstanceImpl.class
// .getDeclaredMethod("loadScriptFromAssets",
// AssetManager.class,
// String.class,
// boolean.class);
// method.setAccessible(true);
// method.invoke(instance, EffectApplication.getInstance().getAssets(), "assets://business.android.jsbundle", false);
// } catch (Exception e) {
// e.printStackTrace();
// }
String path = EffectApplication.getInstance().getExternalCacheDir()+"/business.android.jsbundle";
try {
Method method = CatalystInstanceImpl.class
.getDeclaredMethod("loadScriptFromFile",
String.class,
String.class,
boolean.class);
method.setAccessible(true);
method.invoke(instance, path , path , false);
} catch (Exception e) {
e.printStackTrace();
}
}
注释的是从assets加载,没注释的是从自定义的路径加载,这里我把Bundle放在了app的cache文件夹下。