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);