React Native Android白屏优化终极方案
问题描述我们公司的APP部分模块使用了react native进行开发,使用react native开发确实很爽,一次编写到处运行,前端的开发体验,高效的开发效率,但是我们进入react native模块的时候,会有明显的白屏,时间大概是1-2s,这是很差的用户体验,我们今天的这篇文章就是为了解决这个痛点。 已有方案我相信很多同学可能都看过react native中文网推荐的ReactNative安卓首屏白屏优化这篇文章,这篇文章方案很给力!作者采用了内存换时间的方案,缓存了ReactInstanceManager和ReactRootView对象,我们只需要在应用启动的时候初始化,之后进入react native模块都是调用缓存里的数据,所以速度非常快。 此方案存在的小问题但是试过的同学可能知道这个方案有个小问题:第一次进入react native模块之后,再次进入react native模块,react native 页面的生命周期都不会执行(render, componentDidMount等),因为我们拿的都是已经缓存好的数据,假如我们在react native页面请求数据更新页面,只有第一次进入的时候是有效的。 改进方案
我们这篇文章的重点是Android白屏优化,关于Android原生项目集成react native,请看我另一篇文章Android原生集成react native。 我们现在的方案就是只缓存ReactInstanceManager,每次进入ReactActivity的时候新建一个ReactRootView对象。具体代码如下: public class RNCacheViewManager { private static ReactInstanceManager mManager = null; //init public static void init(Context context) { mManager = createReactInstanceManager(); ReactRootView mRootView = new ReactRootView(context); mRootView.startReactApplication(mManager,"test",null); } public static ReactInstanceManager getReactInstanceManager() { return mManager; } private static ReactInstanceManager createReactInstanceManager() { return ReactInstanceManager.builder() .setApplication(SHApplication.getInstance()) .setBundleAssetName("index.android.bundle") .setJSMainModuleName("index.android") .addPackage(new MainReactPackage()) .setUseDeveloperSupport(true) //开发者支持,开发的时候要设置为true,不然无法使用开发者菜单 .setInitialLifecycleState(LifecycleState.RESUMED) .build(); } }
public class ReactRootActivity extends AppCompatActivity implements DefaultHardwareBackBtnHandler { private ReactRootView mReactRootView; private ReactInstanceManager mReactInstanceManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mReactRootView = new ReactRootView(this); mReactInstanceManager = RNCacheViewManager.getReactInstanceManager(); Bundle bundle = getIntent().getExtras(); mReactRootView.startReactApplication(mReactInstanceManager,bundle); setContentView(mReactRootView); } @Override public void invokeDefaultOnBackPressed() { super.onBackPressed(); } @Override protected void onPause() { super.onPause(); if (mReactInstanceManager != null) { mReactInstanceManager.onHostPause(this); } } @Override protected void onResume() { super.onResume(); if (mReactInstanceManager != null) { mReactInstanceManager.onHostResume(this,this); } } @Override protected void onDestroy() { super.onDestroy(); if (mReactInstanceManager != null) { mReactInstanceManager.onHostDestroy(this); } } @Override public void onBackPressed() { if (mReactInstanceManager != null) { mReactInstanceManager.onBackPressed(); } else { super.onBackPressed(); } } @Override public boolean onKeyUp(int keyCode,KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) { mReactInstanceManager.showDevOptionsDialog(); return true; } return super.onKeyUp(keyCode,event); } } 总结这个问题耽误了我很长的时间,所以我想把我的心路历程分享给大家,这样大家遇到这个问题的时候就可以分分钟搞定,如果我有说的什么不清楚的地方,尽管提问。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |