APP是原生嵌入一个React Native界面
背景
按官方实例集成了一个React Native界面,但每次打开都感觉等待时间有点长,会有白屏状态。这对于强迫症来说简直不能忍。于是决定优化。
效果
优化前的效果,白屏时间较长。
优化后,白屏时间明显变短。
原因
当Android要运行React Native时,需要先加载JSBundle,这块是比较耗时的。
之前的做法是在打开界面的时候才去加载,所以会慢一拍。
优化之后,在App启动时,就初始化JSBundle,然后在RN界面直接使用。
解决方案
创建一个RN加载器的单利
import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.os.Bundle;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactInstanceManagerBuilder;
import com.facebook.react.ReactRootView;
import com.facebook.react.common.LifecycleState;
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
import com.prance.lib.react.pack.MyReactPackage;
/** * JSBundle加载唯一实例 * <p> * Created by bingbing on 2017/5/9. */
public class MyReactInstanceManager {
private static MyReactInstanceManager mInstance;
private ReactInstanceManager mReactInstanceManager;
public static MyReactInstanceManager getInstance() {
if (mInstance == null) {
synchronized (MyReactInstanceManager.class) {
if (mInstance == null) {
mInstance = new MyReactInstanceManager();
}
}
}
return mInstance;
}
/** * 初始化 * * @param context */
public void init(Context context) {
getReactInstanceManager(context);
}
/** * 初始化 ReactInstanceManager * 预加载jsBundle * @param context * @return */
public ReactInstanceManager getReactInstanceManager(Context context) {
Application application = (Application) context.getApplicationContext();
if (mReactInstanceManager == null) {
ReactInstanceManagerBuilder builder = ReactInstanceManager.builder()
.setApplication(application)
.setBundleAssetName("index.android.bundle")
.setJSMainModuleName("index.android")
.setUseDeveloperSupport(false)
.addPackage(new MyReactPackage());
//这里注意!!一定要是LifecycleState.BEFORE_CREATE
//这样当正式加载的时候,才可以获取到mCurrentActivity的引用
builder.setInitialLifecycleState(LifecycleState.BEFORE_CREATE);
mReactInstanceManager = builder.build();
//预加载!!!
mReactInstanceManager.createReactContextInBackground();
}
return mReactInstanceManager;
}
/** * 开启开发者菜单 */
public void showDevOptionsDialog() {
mReactInstanceManager.showDevOptionsDialog();
}
/** * 返回键 */
public void onBackPressed() {
mReactInstanceManager.onBackPressed();
}
/** * 在Activity的onResume中调用 * @param activity * @param handler */
public void onHostResume(Activity activity,DefaultHardwareBackBtnHandler handler) {
mReactInstanceManager.onHostResume(activity,handler);
}
/** * 在Activity的onPause中调用 * * @param activity */
public void onHostPause(Activity activity) {
mReactInstanceManager.onHostPause(activity);
}
/** * 创建ReactRootView实例,并启动React Native * @param context * @param initialProps * @return */
public ReactRootView getRootView(Context context,Bundle initialProps) {
ReactRootView view = new ReactRootView(context);
view.startReactApplication(mReactInstanceManager,"App",initialProps);
return view;
}
/** * 销毁RootView,在Activity的onDestroy中调用 * @param view */
public void destroy(ReactRootView view) {
mReactInstanceManager.detachRootView(view);
}
/** * 销毁Manager,在程序退出或者最后一个RN界面结束时调用 */
public void destroy() {
mReactInstanceManager.onHostDestroy();
}
}
初始化
- 在Application或者第一个界面调用
MyReactInstanceManager.getInstance().init(this);
- 在Activity中调用
ReactRootView rootView = MyReactInstanceManager.getInstance().getRootView(mActivity,initialProps);
setContentView(rootView);