以crazyboycode/react-native-splash-screen为例,给一个RN应用添加一个应用启动屏,以掩盖app启动白屏的问题。
说明:该组件应用场景是在app启动时,由于RN渲染需要时间,因手机性能的问题可能会导致应用2到3秒的白屏时间。因此为了解决该问题,我们给RN应用添加一个Native启动屏,以掩盖这种因启动白屏而引起的不友好的用户交互。

准备工作

开发环境:window10
开发工具:Android Studio、WenStorm

开发步骤

  • 用WebStorm打开一个RN工程,并用Android Studio打开该工程下对应的android项目
  • 创建原生组件SplashScreen,此组件为RN中将要调用到的原生组件
package com.myunionpaydemo;

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

import java.lang.ref.WeakReference;

public class SplashScreen {
private static Dialog mSplashDialog;
private static WeakReference<Activity> mActivity;

public static void show(final Activity activity, final boolean fullScreen) {
if (activity != null) {
mActivity=new WeakReference<>(activity);
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
if (!activity.isFinishing()) {
mSplashDialog = new Dialog(activity);
mSplashDialog.setContentView(R.layout.layout_splash_screen);
mSplashDialog.setCancelable(false);
if (!mSplashDialog.isShowing()) {
mSplashDialog.show();
}
}
}
});
}
}

/**
* 关闭启动屏
*/

public static void hide(Activity activity) {
if (activity == null)
activity = mActivity.get();

if (activity == null) return;

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

}
  • 向JS模块提供SplashScreen组件
    JS不能直接调用Java,所以我们需要为他们搭建一个桥梁Native Modules
    首先,创建一个ReactContextBaseJavaModule类型的类,供JS调用
package com.myunionpaydemo;

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

public class SplashScreenModule extends ReactContextBaseJavaModule {

public SplashScreenModule(ReactApplicationContext reactContext) {
super(reactContext);
}

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

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

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

注意,这里的show()hide()是最终在RN的JS代码中调用的方法,因此需要添加@ReactMethod注解

  • MainApplication中注册SplashScreenModule组件
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new SplashScreenReactPackage()
);
}
  • 在RN的JS模块中调用原生组件
    我们可以在RN中调用我们编写好的原生组件了。
    现在转移到WebStorm里进行调用原生组件的相应工作。
    1.创建一个名为SplashScreen的js文件,添加代码如下:
import {NativeModules} from 'react-native'
export default NativeModules.SplashScreen;

2.在RN应用首页调用相应的方法(此处根据示例要求,我们在componentDidMount方法调用hide()方法,即首页画面已经渲染完成,可以关闭加载启动屏)

import SplashScreen from "./SplashScreen";
...
//渲染之前调用原生组件Dialog遮盖白屏
componentWillMount(){
SplashScreen.show();
}

componentDidMount(){
SplashScreen.hide();
}
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to React Native!
</Text>
<Text style={styles.instructions}>
To get started, edit App.js
</Text>
<Text style={styles.instructions}>
{instructions}
</Text>
{this.getLastView()}
</View>
);
}

getLastView(){
let i=500000000;
//添加循环,模拟复杂页面渲染时的耗时时间
while (i){
i--;
}
return(<Text style={styles.welcome}>
Welcome to React Native!
</Text>);
}
...

至此,调用原生组件的工作就全部完成,最后运行看下效果:

短暂的启动屏一闪而过,效果还不是很好,还是会有短暂的白屏,不过调用原生组件的功能成功实现了Y(·_·)Y

参考资料
1. crazycodeboy/react-native-splash-screen
2. React-Native-启动白屏问题解决方案,教程

Demo 地址:GetNativeModule

更多相关文章

  1. 【Android应用开发技术:应用组件】Android事件处理机制
  2. Android 时间日期选择器的用法
  3. Android开发笔记(四十)组件通讯工具Intent
  4. Android时间日期类小结
  5. android 命令修改时间或程序修改系统时间
  6. 导航架构组件 - 具有CollapsingToolbar的详细信息视图
  7. 在服务中设置服务重复时间
  8. Android自定义控件——开源组件SlidingMenu的项目集成
  9. Android开发四大组件之Service(实例篇)

随机推荐

  1. 如果你现在的生活呆腻了,尝试着去改变一下
  2. java中的final关键字解析
  3. android与服务器交互方式
  4. 2021.1.15 ——运算符及关键字
  5. Android动态化方案
  6. 状态机设计
  7. 聊聊java中的注解
  8. 授权与认证实战
  9. Android(安卓)Studio多渠道打包、自定义
  10. java关键字系列(6)void