先来看下官网对于Native Modules的描述:
Sometimes an app needs access to a platform API that React Native doesn’t have a corresponding module for yet. Maybe you want to reuse some existing Java code without having to reimplement it in JavaScript,or write some high performance,multi-threaded code such as for image processing,a database,or any number of advanced extensions.
We designed React Native such that it is possible for you to write real native code and have access to the full power of the platform. This is a more advanced feature and we don’t expect it to be part of the usual development process,however it is essential that it exists. If React Native doesn’t support a native feature that you need,you should be able to build it yourself.
上面大概的意思是说,我们有时后需要用的API,RN并没有提供。而且我们可能会想用一些现成的java代码,或者写一些高质量、多线程的代码等等。
官网上提供了4种:
- Toast Module
- Callbacks
- Threading
- Sending Event to JavaScript
这篇博客我们只说第一种,其他3中只是大概看下文档,就不写demo了哈。
首先,我们用Android Studio打开我的text项目,等待构建,等构建完毕之后,我们看下目录。
看到,多出来n多的包,这些包都是和RN有关的。
接下来我们写Native Modules
package com.text;
import android.widget.Toast;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import java.util.HashMap;
import java.util.Map;
public class ToastModule extends ReactContextBaseJavaModule{
private static final String DURATION_SHORT_KEY="SHORT";
private static final String DURATION_LONG_KEY="LONG";
public ToastModule(ReactApplicationContext reactContext){
super(reactContext);
}
@Override
public String getName() {
return "ToastAndroid";
}
@Override
public Map<String,Object> getConstants(){
final Map<String,Object> constans=new HashMap<>();
constans.put(DURATION_SHORT_KEY,Toast.LENGTH_SHORT);
constans.put(DURATION_LONG_KEY,Toast.LENGTH_SHORT);
return constans;
}
@ReactMethod
public void show(String message,int duration){
Toast.makeText(getReactApplicationContext(),message,duration).show();
}
}
- 本地module都需要继承ReactContextBaseJavaModule;
- 必须重写getName()方法,返回在 JavaScript 里面表示这个类的叫做 NativeModule 的字符串的名字。在这里我们调用 ToastAndroid 因此我们可以在 JavaScript 里面使用 React.NativeModules.ToastAndroid 来得到它;
- getConstants的方法会将传递给JavaScript的常量返回。并不是 必须实现;
@ReactMethod注解的方法,返回值总是void,供JS调用 。
关于还可重写的其他方法,请自行查看com.facebook.react.bridge.BaseJavaModule和com.facebook.react.bridge.NativeModule
接下来的步骤,注册Modules,这里我和官网的介绍有一点不一样。由于我是直接在原来的上面修改的。所以,我这里不需要写一个实现ReactPackage接口得类,直接在MainReactPackage中修改就行。
注意,如果不是的话,得重新写一个实现ReactPackage接口的类,并在Activity的onCreate方法中通过addPackage()方法加进去。具体参考官方文档,我会在最后给出链接
在createNativeModules返回的list中,多加一个new ToastModule(reactContext)就好。
最后,在js中调用(我这里还用的上次的demo)
var {NativeModules} = require('react-native');
module.exports = NativeModules.ToastAndroid;
var ToastAndroid=require('ToastAndroid');
ToastAndroid.show('quanshijie',ToastAndroid.SHORT);
直接上效果图:
参考资料:Native Modules官方文档