在使用React Native(RN) 开发时,由于RN技术比较新,框架与控件相对较少,这时很自然就想到的RN如何调用Native以及如何进行通讯,个人感觉这块是开发必须要掌握的,今后的开发模式肯定是Hybird模式,由于初学,所以先按照文档流程跑通,至于原理后期再研究。
Module 0 is not a registered callable module.
1.创建一个dialog的module 继承自ReactContextBaseJavaModule
package com.listviewdem;
import android.view.View;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
/**
* Created by plus on 16/7/19.
* 自定义删除对话框-->RN 调用
*/
public class ReactRemoveChannelModule extends ReactContextBaseJavaModule{
public static final String REACT_CLASS = "RCTRemoveChannel";
public ReactRemoveChannelModule(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return REACT_CLASS;
}
//注写 该方法为RN调用方法.
@ReactMethod
public void show(String title, final Callback callback){
final RemoveChannelDialog removeChannelDialog=new RemoveChannelDialog(getCurrentActivity());
removeChannelDialog.show(title);
removeChannelDialog.setPositiveButtonListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
removeChannelDialog.dismiss();
//回调给RN
callback.invoke(true);
}
});
}
}
简单说明下:
- getName方法返回的是JS中组件的名称.(模块名前的RCT前缀会被自动移除。)
- 自定义RN调用的方法。注:需要加上注解@ReactMethod
RemoveChannelDialog是自定义Dialog,对有过安卓开发经验的应该很简单。
2.接下来我们要将创建好的module添加到package中,然后注入该模块。
创建一个类实现ReactPackage接口,在createNativeModules方法中封装好自定义的module。
package com.listviewdem;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Created by plus on 16/7/19.
* 实现ReactPackage接口封装NativeModule实体。
*/
public class RNJavaReactPackage implements ReactPackage {
//将创建的NativeNModule封装返回
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules=new ArrayList<>();
modules.add(new ReactRemoveChannelModule(reactContext));
return modules;
}
@Override
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return new ArrayList<>();
}
}
这里有个诡异的问题,纠结我好久,多亏了群里一个朋友提醒了我,主要是因为相关资料太少,遇到问题无从下手.
- 在0.29版本以前,我们是通过MainActivity也就是基于ReactActivity加入的,但是在0.29版本以后应该通过MainApplication也就是基于ReactApplication加入的.
package com.listviewdem;
import android.app.Application;
import android.util.Log;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import java.util.Arrays;
import java.util.List;
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
protected boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),new RNJavaReactPackage()
);
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
}
到这里我们java端就完成了,后面的就是在RN端如何进行调用.
在RN中,首先引入NativeModules,通过NativeModules获取到我们自定义原生的控件.
var {NativeModules}=require('react-native');
var dialog=NativeModules.RemoveChannel;//原生组件.
/**
长按事件
**/
onLongPress(data){
dialog.show(data.name,(msg)=>{
alert('移除成功');
});
}
这样我们就完成了react native调用Native 控件.是不是很实用.
效果图:
以上需求对产品而言其实没有多大作用,这里只是简单介绍了下react native 该如何调用安卓原生控件,在实际的项目开发中,应该根据自身项目情况来决定,后续我会将这个完整的项目放到github供大家参考。