React Native Android启动白屏的一种解决方案下

实现思路

思路大流程:

1.APP启动的时候控制ReactActivity从而显示启动屏。
2.编写原生模块,提供一个关闭启动屏的公共接口。
3.在js的适当位置(一般是程序初始化工作完成后)调用上述公共接口关闭启动屏。

目录结构

SplashScreen:创建Diaolg,当白屏的时候显示用。
SplashScreenModule、SplashScreenReactPackage:Dialog关闭的桥接,需要在MainApplication中注册。
lanuch_screen.png:Dialog布局文件显示的图片
splash.xml:Dialog加载的布局配置文件

开始动手

1.在android/app/src/main/java/com/splashScreen下创建一个文件SplashScreen.java

package com.splashScreen;

import android.app.Activity;
import android.app.Dialog;

import com.nativetest.R;

import java.lang.ref.WeakReference;

public class SplashScreen {

    private static int NULL_ID = 0;
    private static Dialog mSplashDialog;
    private static WeakReference<Activity> mActivity;

    /**
     * 打开启动屏
     */
    public static void show(final Activity activity, final boolean fullScreen, final int themeResId){
        if (activity==null) return;
        mActivity = new WeakReference<Activity>(activity);
        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (!activity.isFinishing()) {
                    mSplashDialog = new Dialog(
                            activity,
                            themeResId !=NULL_ID ? themeResId
                                    : fullScreen ? R.style.SplashScreen_Fullscreen
                                    : R.style.SplashScreen_SplashTheme

                    );
                    mSplashDialog.setContentView(R.layout.splash);
                    mSplashDialog.setCancelable(false);
                    if (!mSplashDialog.isShowing()) {
                        mSplashDialog.show();
                    }
                }
            }
        });
    }

    /**
     * 打开启动屏
     */
    public static void show(final Activity activity, final boolean fullScreen) {
        show(activity, fullScreen, 0);
    }

    /**
     * 打开启动屏
     */
    public static void show(final Activity activity) {
        show(activity, false);
    }

    /**
     * 关闭启动屏
     */
    public static void hide(Activity activity) {
        if (activity == null) {
            if (mActivity == null) {
                return;
            }
            activity = mActivity.get();
        }
        if (activity == null) return;

        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (mSplashDialog != null && mSplashDialog.isShowing()) {
                    mSplashDialog.dismiss();
                    mSplashDialog = null;
                }
            }
        });
    }

}

2.在android/app/src/main/java/com/splashScreen下创建一个文件SplashScreenModule.java

package com.splashScreen;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.splashScreen.SplashScreen;

public class SplashScreenModule extends ReactContextBaseJavaModule {
    public SplashScreenModule(ReactApplicationContext reactContext) {
        super(reactContext);
    }

    @Override
    public String getName() {
        return "SplashScreen";
    }

    /**
     * 打开启动屏
     */
    @ReactMethod
    public void show() {
        SplashScreen.show(getCurrentActivity());
    }

    /**
     * 关闭启动屏
     */
    @ReactMethod
    public void hide() {
        SplashScreen.hide(getCurrentActivity());
    }

    /**
     * 退出程序
     */
    @ReactMethod
    public void exit() {
        if (getCurrentActivity() != null)
            getCurrentActivity().finish();
        System.exit(0);
    }

}

3.在android/app/src/main/java/com/splashScreen下创建一个文件SplashScreenReactPackage.java

package com.splashScreen;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import com.splashScreen.SplashScreenModule;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class SplashScreenReactPackage implements ReactPackage {

    // Deprecated RN 0.47
    public List<Class<? extends JavaScriptModule>> createJSModules() {
        return Collections.emptyList();
    }

    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }

    @Override
    public List<NativeModule> createNativeModules(
            ReactApplicationContext reactContext) {
        List<NativeModule> modules = new ArrayList<>();
        modules.add(new SplashScreenModule(reactContext));
        return modules;
    }
}

4.在MainActivity.java中添加如下代码

package com.nativetest;

import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;

import com.facebook.react.ReactActivity;
import com.splashScreen.SplashScreen;


// import com.splashScreen.SplashScreen;

public class MainActivity extends ReactActivity {

    /**
     * Returns the name of the main component registered from JavaScript.
     * This is used to schedule rendering of the component.
     */
    @Override
    protected String getMainComponentName() {
        return "NativeTest";
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        SplashScreen.show(this,true);//显示Dialog
        super.onCreate(savedInstanceState);
        //解决应用程序多次重启问题
        if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0){
            finish();
            return;
        }
    }
}

5.在android/app/src/main/res下新建一个drawable文件夹,该文件夹下放置一个启动屏图片命名为launch_screen.png

6.在android/app/src/main/res下新建一个layout文件夹,该文件夹下新建一个layout.xml文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/launch_screen"
    >
</LinearLayout>

猜你喜欢

转载自www.cnblogs.com/fe-linjin/p/10685676.html