React Native与Android通信交互

  安卓系统为我们提供了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

}  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值