ReactNative学习笔记——调用原生模块(Android)
Posted mictoy_朱
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ReactNative学习笔记——调用原生模块(Android)相关的知识,希望对你有一定的参考价值。
以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
以上是关于ReactNative学习笔记——调用原生模块(Android)的主要内容,如果未能解决你的问题,请参考以下文章