react native載入多個jsbundle(assets和其他目錄)
阿新 • • 發佈:2018-12-10
在使用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資料夾下。