[React Native] Android 白屏优化

前端之家收集整理的这篇文章主要介绍了[React Native] Android 白屏优化前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

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

}

初始化

  1. 在Application或者第一个界面调用
MyReactInstanceManager.getInstance().init(this);
  1. 在Activity中调用
ReactRootView rootView = MyReactInstanceManager.getInstance().getRootView(mActivity,initialProps);
setContentView(rootView);

万事大吉

原文链接:https://www.f2er.com/react/303948.html

猜你在找的React相关文章