博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
React Native与Android通信交互
阅读量:6214 次
发布时间:2019-06-21

本文共 3605 字,大约阅读时间需要 12 分钟。

  安卓系统为我们提供了webview来加载网页,为了让webview加载的网页可以与App交互,系统提供了一套机制帮助我们更方便的实现通信。同样为了实现React Native与原生App之间的通信,Facebook也实现了自己的一套交互机制.

通过平时与IOS和安卓的同学同事调试,大致归纳了有以下四种:

  1. RCTDeviceEventEmitter 事件方式

  2. Callback 回调方式

  3. Promise 信任方式

  4. 直传常量数据

先比较下优缺点:eventMitter的形式可任意时刻传递,由Native主导控制,callback形式由JS调用Native返回,但是是异步的时机不确定,所以有Promise形式,但是要不断的JS调用如轮询。直传常量跨域传值,只能从原生端向RN端传递。RN端可通过 NativeModules.[module名].[参数名] 的方式获取

了解了三者的通信方式,怎么能少了代码的描述!我们来看看代码如何实现。大致的实现步骤如下:

以下是安卓代码的编写 eventMitter

1. 定义Module类,继承ReactContextBaseJavaModule, 在Module类中,我们定义交互的方法,例如RN调用Native的方法,Native调用RN的方法等。

@Override

public String getName() {

return MODULE_NAME;

}

/**

* RN调用Native的方法在module中定义一个方法,并用@ReactMethod 注解标注:表明该方法会被RN调用。即被RN调用的原生方法必须使用@ReactMethod注解标注。

*/

@ReactMethod

public void rnCallNative(String a) {

// XXX.

    mContext.startActivity(XX);

}

/**

* Native调用RN 上面代码定义了原生方法,通过在Android层调用RN层。使用ReactContext的getJSModule方法,emit来发送消息。同样,emit的第一个参数要与RN层中addListener方法的第一个参数相同。

* @param msg

*/

public void nativeCallRn(String msg) {         mContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(  EVENT_NAME,msg);

}

2. 定义Package类,继承ReactPackage实现Package的createNativeModules方法,将Module实例添加到集合。

/** 通信Package类 */

public class CommPackage implements ReactPackage {

    public CommModule mModule;

/**

* 创建Native Module 在createNativeModules方法中,初始化集合,并将module实例添加进集合,返回集合实例。

* @param reactContext

*/

@Override

public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {

    List<NativeModule> modules = new ArrayList<>();

    mModule = new CommModule(reactContext);

    modules.add(mModule);

    return modules;

}

@Override

public List<Class<? extends JavaScriptModule>> createJSModules() {

    return Collections.emptyList();

}

@Override

public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {

    return Collections.emptyList();

  }

}

3. 定义Application,继承ReactApplication实现getPackages方法,将Package实例添加到getPackages下的集合。

private static final CommPackage mCommPackage = new CommPackage();

**

* 获取 reactPackage getPackages方法中,将Package实例添加到Arrays中即可完成注册

*/

public static CommPackage getReactPackage() {

    return mCommPackage;

}

以下是RN代码的编写,通过 RCTDeviceEventEmitter 模式进行通信交互。交互都是以主动方式为主

1. 调用原生代码

/**

* 调用原生代码 在React Native层,通过NativeModules调用commModule

*/

nativeCall() {

    NativeModules.commModule.rnCallNative(xxx);

}

2. 接收原生调用

/**

* 接收原生调用通过DeviceEventEmitter注册监听,类似于Android中的监听事件。第一个参数标识名称,要与Module中emit的Event Name相同。第二个参数即为处理回掉IOS应该为NativeEventEmitter

*/

componentDidMount() {

    DeviceEventEmitter.addListener('nativeCallRn',(msg)=>{ });

}

Callback形式 RN层调用Native层,Native层处理完成后,回调RN层

**

* Callback 方式

* rn调用Native,并获取返回值

*/

@ReactMethod

public void rnCallNativeCb(String msg, Callback callback) {

callback.invoke(xxx); // 2.回调RN,即将处理结果返回给RN

}

// RN

callbackComm(msg) {

    NativeModules.commModule.rnCallNativeCb(msg,(result) => {})

}

Promise形式 同样是RN层调用Native层,Native层处理完成后,回调RN层

@ReactMethod

public void rnCallNativePromise(String msg, Promise promise) {

    promise.resolve(xxx);

}

// RN

promiseComm(msg) {

NativeModules.commModule.rnCallNativePromise(msg).then((result) =>{}).catch((error)           =>  {console.log(error)});

}

直传常量数据(原生向RN)

@Nullable

@Override

@return a map of constants this module exports to JS. Supports JSON types.

从源码注释中可以看出,该方法是返回一个Map类型的常量,导出到JS端(即RN)。支持JSON 类型。所以,我们只需要重写方法,声明Map集合,向其中添加常量后,返回即可

public Map<String, Object> getConstants() {

    return super.getConstants();

}

// Ours Android

@Nullable

@Override

public Map<String, Object> getConstants() {

    Map<String,Object> params = new HashMap<>();

    params.put("Constantxx","xxx");

    return params;

}

// Ours RN

componentWillMount() {

    let result = NativeModules.MyModule.Constantxx

}  

转载地址:http://kdpja.baihongyu.com/

你可能感兴趣的文章
规格模式取代sql查询代码
查看>>
javascript引用动态变量名的变量值
查看>>
实现struts2零配置流程
查看>>
用maven+springMVC创建一个项目 【转】
查看>>
Wireshark过滤规则实践第一篇:显示过滤器
查看>>
U-boot在S3C2440上的移植详解(五)--- yaffs2文件系统下载
查看>>
android通过okhttp访问自签名https网站(单向)
查看>>
[leetcode] Valid Sudoku
查看>>
【Homebrew】Error: Failure while executing: git config --local --replace-all homebrew.private true
查看>>
lua面向对象编程
查看>>
Cobbler极简教程
查看>>
rpm包安装过程中依赖问题“libc.so.6 is needed by XXX”解决方法
查看>>
js--页面元素位置
查看>>
[FindBugs分析记录]use of non-short-circuit logic
查看>>
Eclipse插件开发-不使用对话框,使用代码方式生成bundle jar
查看>>
数值计算---基于梯度的优化方法
查看>>
Factory Method Pattern(工厂方法模式)——莫勇鹏老师
查看>>
【原创】hoisie/web 脑图
查看>>
Java Double相加出现的怪事
查看>>
MapReduce:详解Shuffle过程---map和reduce数据交互的关键
查看>>