React Native创建原生模块
我的博客原文地址 开发模块实现模块下面我们就通过实现一个自定义模块,来熟悉编写原生模块需要用的一些知识。该模块主要实现调用一些Android原生的功能,比如弹 public class MyNativeModule extends ReactContextBaseJavaModule {
private final static String MODULE_NAME = "MyNativeModule";
private ReactApplicationContext mContext;
public MyNativeModule(ReactApplicationContext reactContext) {
super(reactContext);
mContext = reactContext;
}
@Override
public String getName() {
return MODULE_NAME;
}
@Nullable
@Override
public Map<String,Object> getConstants() {
final Map<String,Object> constants = new HashMap<>();
constants.put("SHORT",Toast.LENGTH_SHORT);
constants.put("LONG",Toast.LENGTH_LONG);
constants.put("NATIVE_MODULE_NAME",MODULE_NAME);
return constants;
}
@ReactMethod
public void startActivity(){
Intent intent = new Intent(mContext,SecondActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
}
@ReactMethod
public void showToast(String msg,int duration){
Toast.makeText(mContext,msg,duration).show();
}
}
React Native调用的方法需要使用@ReactMethod注解。 参数类型原生Java数据类型和JS数据类型的映射关系: Boolean -> Bool
Integer -> Number
Double -> Number
Float -> Number
String -> String
Callback -> function
ReadableMap -> Object
ReadableArray -> Array
详情参考:ReadableMap和ReadableArray 导出常量可以实现 @Nullable
@Override
public Map<String,MODULE_NAME);
constants.put(TestEvent,TestEvent);
return constants;
}
注册模块然后我还要注册这个模块,通过实现 public class MyReactPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new MyNativeModule(reactContext));
return modules;
}
@Override
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
添加模块在 @Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),new MyReactPackage()
);
}
或者是在 @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mReactRootView = new ReactRootView(this);
mReactInstanceManager = ReactInstanceManager.builder()
.setApplication(getApplication())
.setBundleAssetName("index.android.bundle")
.setJSMainModuleName("index.android")
.addPackage(new MainReactPackage())
.addPackage(new MyReactPackage())
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build();
mReactRootView.startReactApplication(mReactInstanceManager,"HelloWorld",null);
setContentView(mReactRootView);
}
封装模块为了使JavaScript端访问起来更为方便,通常我们都会把原生模块封装成一个JavaScript模块。在 'use strict';
import { NativeModules } from 'react-native';
// 这里的MyNativeModule必须对应
// public String getName()中返回的字符串
export default NativeModules.MyNativeModule;
调用模块现在,在别处的JavaScript代码中可以这样调用你的方法: import MyNativeModule from './MyNativeModule';
class HelloWorld extends React.Component {
startActivity(){
console.log("MODULE NAME: ",MyNativeModule.NATIVE_MODULE_NAME);
MyNativeModule.startActivity();
}
showToast(){
console.log("MODULE NAME: ",MyNativeModule.NATIVE_MODULE_NAME);
MyNativeModule.showToast("From JS",MyNativeModule.LONG);
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress={this.startActivity}>
<Text style={styles.hello}>start Activity</Text>
</TouchableOpacity>
</View>
)
}
}
其他特性React Native的跨语言访问是异步进行的,所以想要给JavaScript返回一个值的唯一办法是使用回调函数或者发送事件。 回调函数原生模块还支持一种特殊的参数——回调函数。它提供了一个函数来把返回值传回给JS。 @ReactMethod
public void testCallback(int para1,int para2,Callback resultCallback){
int result = para1 + para2;
resultCallback.invoke(result);
}
可以在JS中调用: testCallback(){
MyNativeModule.testCallback(100,100,(result) => { console.log("result: ",result); //'result: ',200 }); }
原生模块通常只应调用回调函数一次。但是,它可以保存callback并在将来调用。 发送事件到JavaScript原生模块可以在没有被调用的情况下往JavaScript发送事件通知。最简单的办法就是通过 public void sendEvent(){
WritableMap params = Arguments.createMap();
params.putString("module","MyNativeModule");
mContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(TestEvent,params);
}
在JS中这样调用: import { DeviceEventEmitter } from 'react-native';
......
componentWillMount() {
console.log("componentWillMount");
//接收事件
DeviceEventEmitter.addListener(MyNativeModule.TestEvent,info => {
console.log(info);
});
}
Promise如果对ES6的 @ReactMethod
public void testPromise(Boolean isResolve,Promise promise) {
if(isResolve) {
promise.resolve(isResolve.toString());
}
else {
promise.reject(isResolve.toString());
}
}
在JS中调用: testPromise(){
MyNativeModule.testPromise(true)
.then(result => {
console.log("result1 is ",result);
})
.catch(result => {
console.log("result2 is ",result);
});
}
从startActivityForResult中获取结果参考官方文档 监听生命周期监听activity的生命周期事件(比如 public MyNativeModule(ReactApplicationContext reactContext) {
super(reactContext);
mContext = reactContext;
//添加监听
reactContext.addLifecycleEventListener(this);
}
实现 @Override
public void onHostResume() {
Log.e(MODULE_NAME,"onHostResume");
}
@Override
public void onHostPause() {
Log.e(MODULE_NAME,"onHostPause");
}
@Override
public void onHostDestroy() {
Log.e(MODULE_NAME,"onHostDestroy");
}
然后就可以监听ReactNative应用的生命周期了。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |