zoukankan      html  css  js  c++  java
  • 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>
    
  • 相关阅读:
    Python3字典中items()和python2.x中iteritems()有什么区别
    python中使用zip函数出现<zip object at 0x02A9E418>
    python中字符串连接的四种方式
    Python如何规定对方输入的数字必须是整数?
    C# 自定义控件VS用户控件
    c#使用Split分割换行符
    C# 读取app.config配置文件 节点键值,提示 "配置系统未能初始化" 错误的解决方案
    安装MySql for Visual Studio的坑
    MySql Access denied for user 'root'@'localhost' (using password:YES) 解决方案
    VS2010 VS2012 VS2013 VS2015启动调试时老是提示正在下载公共符号
  • 原文地址:https://www.cnblogs.com/fe-linjin/p/10685676.html
Copyright © 2011-2022 走看看