正如上篇文章[React Native]移植原生Android项目中提到,ReactNative目前更多的是用于在原生App中加入一个新的模块。那么,此时如果这个ReactNative模块需要使用到一些原生模块的功能,比如访问平台的API;或者你要复用现成的Java代码;又或者使用Java已经成熟的第三方Library,那么这篇文章会一步步告诉你,如何去调用一个已经封装好的Android原生代码。
实际上,正如上篇文章[React Native]移植原生Android项目中提到,目前更多的还是使用React来做V的工作,那么诸如网络请求之类还是通过在ReactNative模块中调用原生已经封装好的库来实现(据说饿了么目前就是这个方案~)
为了更好的理解,本文演示如何在ReactNative中使用Android平台的Toast功能。
步骤一:新建ReactNative项目
使用下面的命令新建一个ReactNative项目,确保你的环境已经配置正确,有问题可以参考[React Native]入门篇
react-native init Demo2
让我们运行下新建的项目,效果如下
步骤二:新建原生模块
用AS开发工具打开Demo2
目录下的android项目,新建一个classToastModule
继承ReactContextBaseJavaModule
,我们的目标是在JS
中这样写ToastAndroid.show("Test Toast",ToastAndroid.SHORT)
,来显示一个Toast
。
public class ToastModule extends ReactContextBaseJavaModule {
public ToastModule(ReactApplicationContext reactContext) {
super(reactContext);
}
}
ReactContextBaseJavaModule
要求实现getName
方法,该方法返回一个String
,表示模块的名称,这里返回ToastAndroid
。
@Override
public String getName() {
return "ToastAndroid";
}
一个可选的方法getConstants
,用来封装常量给JS
模块使用,比如我们将要用到的常量ToastAndroid.SHORT
。
@Override
public Map<String, Object> getConstants() {
final Map<String, Object> constants = new HashMap<>();
constants.put(DURATION_SHORT_KEY, Toast.LENGTH_SHORT);
constants.put(DURATION_LONG_KEY, Toast.LENGTH_LONG);
return constants;
}
Java
中的方法需要导出才能给JS
使用,要导出Java方法
,需要使用@ReactMethod
来注解,且方法的返回值只能是void
。
@ReactMethod
public void show(String message, int duration) {
Toast.makeText(getReactApplicationContext(), message, duration).show();
}
这样,我们的原生模块已经创建完毕,下面需要注册原生模块了。
步骤三:注册原生模块
新建一个classMyReactPackager
,实现ReactPackager
接口,我们需要实现createNativeModules
方法,该方法返回所有需要被加载的原生模块。
public class MyReactPackager implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> viewManagers = new ArrayList<>();
viewManagers.add(new ToastModule(reactContext));
return viewManagers;
}
@Override
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList(); // 返回null会报错
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList(); // 返回null会报错
}
}
我们新建的MyReactPackager
,需要在MainActivity
的getPackages
中注册并返回。
/**
* A list of packages used by the app. If the app uses additional views
* or modules besides the default ones, add more packages here.
*/
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new MyReactPackager() // 这是我们自定义的ReactPackager
);
}
到此原生模块的工作已经告一段落,下面让我们看下如下在ReactNative
中调用我们的原生模块。
步骤四:使用原生模块
打开index.android.js
文件,在render
方法中用TouchableOpacity
封装一个可以点击的视图Text
,文本内容为Click to show native Toast
。
render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress={this.onPressButton}>
<Text style={styles.instructions}>
Click to show native Toast
</Text>
</TouchableOpacity>
</View>
);
}
在JS
文件中,引入我们步骤二中新建的原生模块ToastAndroid
var ToastAndroid = require('ToastAndroid');
TouchableOpacity
点击方法为onPressButton
,它会调用原生模块导出的show
方法。
onPressButton() {
ToastAndroid.show('Android Toast', ToastAndroid.SHORT);
}
让我们运行下项目,最终效果图如下:
本文的源码地址:Demo2
下一篇文章会介绍JS调用原生模块的高级用法,敬请期待~
2024 - 快车库 - 我的知识库 重庆启连科技有限公司 渝ICP备16002641号-10
企客连连 表单助手 企服开发 榜单123