在 android 中加载 React Native 包之前保持 SplashScreen

Persisting SplashScreen until react native bundle is loaded in android

我遵循了这篇文章中的 android 指南 How to Add a Splash Screen to a React Native App

并且到了我的 SplashScreen activity 在我的主要 activity 之前启动的地步,即 android 应用程序正在膨胀。

到目前为止一切顺利,但我想删除由反应本机 js 包加载引起的白色闪烁。文章建议使用 react-native-splash-screen 库,但是我想将依赖性降到最低。

React 本机文档有这个 Pro Tip 基本上实现了我正在寻找的东西,但在 iOS 中(它在未加载包时一直显示启动画面)。我想弄清楚如何在原生 java 中为 android 做类似的事情,但到目前为止运气不好。

使用rn-splash-scren。当你的反应组件加载时,只需调用

import SplashScreen from "rn-splash-screen";

// Hide the active splash screen

SplashScreen.hide();

您需要从本机端进行设置,但这很容易。

这是一种在 React 添加内容时执行此操作的方法:

=== MainActivity.java ===

import com.facebook.react.*;
import android.content.Context;
import android.app.Activity;
import android.util.Log;
import android.view.View;

public class MainActivity extends ReactActivity {
    class CustomReactActivityDelegate extends ReactActivityDelegate {
        class CustomReactRootView extends ReactRootView {
            public CustomReactRootView(Context context) {
                super(context);
            }
            @Override
            public void onViewAdded(View child) {
                 super.onViewAdded(child);
                 Log.d("React views started to appear", "Static js code has already run");
            }
        }
        private Activity currentActivity;
        public CustomReactActivityDelegate(Activity activity, String mainComponentName) {
            super(activity, mainComponentName);
            currentActivity = activity;
        }
        protected ReactRootView createRootView() {
            return new CustomReactRootView(currentActivity);
        }
    }
    @Override
    protected ReactActivityDelegate createReactActivityDelegate() {
        return new CustomReactActivityDelegate(this, getMainComponentName());
    }
    ...
}

如您所见,我们的想法是覆盖一些东西以挂接到需要的时刻。

您可以在那些 类 中看到其他内容,但通常反应加载与 jni 函数异步捆绑,所以我不确定那里有很多事情要做。你可以覆盖一个链

  1. MainApplication(赋值mReactNativeHost)->
  2. ReactNativeHost.createReactInstanceManager(复制原始方法但调用ReactInstanceManagerBuilder.setJSBundleLoader)->
  3. JSBundleLoader(将原来的JSBundleLoader.createAssetLoader包装成自定义子类,会在loadScript中调用inner loader,然后还会调用CatalystInstanceImpl.callFunction)->
  4. CatalystInstanceImpl.PendingJSCall 只是 运行 你需要的 运行 在那里。

换句话说,这太可怕了,而且 React 仍然不能保证 PendingJSCall 在 bundle 加载之前不会 运行。