旧机宝开发笔记之:RN应用和Native应用之间的通信(回调)

虽然完成了RN对原生方法最简单的调用,但是这种调用是单向的、没有回应的,这让很多需要“交互”的逻辑很难进行,现在我们模仿原生代码来寻找解决方案。

思路

java类中的方法是怎样和调用者“交互”的呢?常见方法如下:

  1. 利用方法的返回值
  2. 传一个回调/方法进来,直接回调调用方提供的逻辑
  3. 发消息/广播等把结果通知出去

我们可以模仿java思路来试试RN是否可行。然后再看看RN有没有什么自己独有的方法。

利用方法的返回值

我们在自定义的工具类里增加一个方法:

@ReactMethod
    public String getMessageToShow(){
        return "ha";
    }

然后我们尝试在RN中用Toast显示并打印出来调用这个方法的结果:

  _onPress() {
    NativeModules.ToastUtil.show(NativeModules.ToastUtil.getMessageToShow());
    console.log('返回结果:' + NativeModules.ToastUtil.getMessageToShow());
  }

一直到编译运行都没毛病!然而当我们点击RN应用中的按钮后,虽然见到了熟悉的Toast,但是Toast显示内容是空的,在看日志:
在这里插入图片描述
果然没有这么简单,方法的返回值并没有被传递回来。这跟RN“传递”方法的方式有关,现在只要知道这种方法并不可行就好了。

使用回调

回调的使用场景非常广泛,跟用于同步的方法的返回值不同,回调多用于异步操作。找了下,RN中还真的提供了回调方法:Callback,其位置在com.facebook.react.bridge.Callback。那么我们尝试来在方法中添加一个参数用于传送过来一个Callback,并通过Callback让原生代码可以回调到RN应用中去。

    @ReactMethod
    public void show(String message, Callback callback){
        Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
        callback.invoke(message);
    }

Callback只有一个invoke方法,传入的是不定长度的参数,我们尝试把Toast显示的message信息通过回调返回给RN。
在RN中,我们增加一个方法作为参数传递给调用的原生方法,并在这个方法里打印原生传过来的内容message:

  _onPress() {
    NativeModules.ToastUtil.show('哈哈', message => {
      console.log('回调结果:' + message);
    });
  }

ok,部署下,点击按钮,出现了熟悉的Toast,在看日志:
在这里插入图片描述
真的把“哈哈”给回调回来了。改动不多。

发消息/广播

发消息、广播也是一个“交互”的方式,但是如果只是想调用一个方法得到它的回应就显得有些不大适用了。只有在现成的调用方式不能满足要求的时候才会想到发送消息/广播这一做法。甚至现在用到的RN调原生、回调,在底层可能也是通过消息机制来实现的。有一定是有的,但是现在还用不到,就放在之后的章节研究吧。

现在我们知道RN中调用原生方法的应答方式有两种了:回调和发消息/广播,回调很简单传个方法/函数过去就好了,发消息/广播可以放到以后来倒腾,那RN有没有自己独有的方式呢?
还真有,Promise,一种进阶“回调”?

Promise

promise是javascript最新语法的内容,你可以在这里快速进行一个大概的了解:
快速了解promise
来点代码会加深你的印象,我们把之前的回调换成promise来试试:
首先是原生代码处的传入参数由Callback修改为Promise:

    @ReactMethod
    public void show(String message, Promise promise){
        Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
        promise.resolve(message);
    }

你应该已经了解了promise的“成功”回调用resolve,失败用reject。
然后我们要把RN逻辑里调用原生代码的位置的Callback处理掉,这里就是直接删除就好了,RN会自动判断原生的方法最后一个参数是不是promise,如果是的话会直接返回一个promise回来的,我们现在去掉callback,直接使用RN自动返回的promise来处理回调:

      <Button
        onPress={() => {
          NativeModules.ToastUtil.show('哈哈')
            .then(message => {
              console.log('promise回调的message为:' + message);
            })
            .catch(() => {
              console.log('上面的函数出错了/回调到reject了');
            });
        }}
        title={'使用promise回调'}
      />

这里和之前回调的区别是:直接去掉了callback这个回调函数,而是把show()方法的返回值作为一个promise来使用(本来就是一个RN返回的promise),然后在then里传入函数来处理成功回调,在catch里传入函数来处理失败回调,以及成功回调里捕获到异常也会再执行catch。
点击这个按钮会看到熟悉的Toast,并且控制到也会打印出:
在这里插入图片描述

从用法上来看,callback是RN调用的时候传递过去的,而promise是RN生成在原生逻辑处使用并直接返回给RN应用中调用的原生方法的,使用上基本就是:
原生逻辑传入RN生成的promise,操作成功调用resolve,失败调用reject,在RN应用中调用原生方法的时候,then传入函数处理成功回调,catch传入函数处理失败回调的情况以及then里传入成功回调函数执行的时候发生异常的情况。
到这,回调的用法基本就ok了,至于promise的理解、高阶用法,已经RN和原生应用之间互发消息将放在之后的章节中提及。先积硅步吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值