zoukankan      html  css  js  c++  java
  • [技术博客]react native事件监听、与原生通信——实现对通知消息的响应

    在react native中会涉及到很多页面之间的参数传递问题。静态的参数传递通常利用组件的Props属性,在初始化组件时即可从父组件中将参数传递到子组件中。对于非父子关系的组件来说,无法直接传递参数,此时可能会用到react-navigation来传递;此外,若要将异步函数、不可预料的事件执行等得到的参数用于页面刷新时,前述的方法都不太奏效。

    DeviceEventEmitter

    react-native中采用了DeviceEventEmitter来实现对事件的监听,实现非父子关系的页面之间的通信。具体来说,我们可以在一个页面中通过DeviceEventEmitter来对特定名称的事件进行监听,此后每当其它位置发送该名称的事件,都会触发这个监听的响应并执行对应的函数。

    DeviceEventEmitter优点在于一次注册多次响应,并且注册后的监听事件是全局性的。不仅如此,通过DeviceEventEmitter还可以与原生模块进行交互。

    基本语法

    导入DeviceEventEmitter

    首先要引入DeviceEventEmitter,DeviceEventEmitter在原生库中,直接引入即可:

    import { DeviceEventEmitter } from 'react-native';
    

    注册监听事件

    通常来说我们会在组件加载完成后开始监听事件:

    componentDidMount(){
           this.emitter = DeviceEventEmitter.addListener('eventName’, function);
    };
    

    addListener('eventName’, function);拥有两个参数,第一个参数是监听事件的名称,为字符串类型;第二个参数是触发监听事件后的回调函数。

    发送监听事件

    注册监听后,我们可以在任意位置直接使用DeviceEventEmitter.emit('eventName',params)来广播一个事件。该函数也有两个参数。第一个参数同样为事件名称;第二个参数为可选项,用于参数的传递。

    卸载监听事件

    当页面卸载时,卸载监听事件:

    componentWillUnmount() {
        this.emitter.remove()
    }
    

    与原生通信

    只需要在原生模块中广播该事件即可。具体代码如下:

    private void sendEvent(ReactContext reactContext,String eventName, @Nullable WritableMap params) {
      reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
          .emit(eventName, params);
    }
    

    上述代码发送了一个名为eventName的包含params参数的事件,值得注意的是发送该事件的前提是react native环境已经加载完成,需要获取其上下文ReactContext。

    示例——react native响应通知消息点击事件

    react native无法直接监听广播事件,因此需要用到原生模块协助。此处通过两次监听事件,采用安卓原生广播+安卓与react native通信来实现react native对通知消息点击事件的响应。

    获取通知内容

    第一步采用通过安卓原生模块监听通知点击事件(参见安卓广播机制)并获取到通知携带的参数信息。

    public static class NotificationReceiver extends BroadcastReceiver {
    	@Override
    	public void onReceive(Context context, Intent intent) {
            if(intent.getAction().equals("androidNotification")){//响应通知事件
                String params = intent.getExtras().getString("params");
                if(params != null){
                    sendEventToRn("RNnotification",params);//发送事件给RN
                }
            }
        }
    }
    
    public static void sendEventToRn(String eventName, @Nullable String params){
    	//这里的模块中context已经获取
        context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                .emit("notification", params);
    }
    

    'RNnotification','androidNotification'为静态注册的广播接收器。广播的发送需要在通知消息的设置处自定义。本项目中处理过程如下:

    Intent intent =new Intent();
    intent.setAction("androidNotification");
    intent.putExtra("params",msg.getRaw().toString());
    Activity currentActivity = MainActivity.getCurrentActivity();//这里获取的是当前activity
    currentActivity.sendBroadcast(intent);
    

    然后在react native中监听通知事件'RNnotification'

    DeviceEventEmitter.addListener('notification',this.notification);
    console.log('开始监听通知');
    
    notification = (paramString) =>{
    	//...此处实现了根据参数导航到指定页面
    }
    

    大功告成。

  • 相关阅读:
    类模型NLP 学习笔记 05 (Brown Clustering && Global Linear Models)
    nullnull精美的文言文表白,一起体会吧!
    [转载]ESFramework介绍之(31)―― 消息分类及对应的处理器
    【转载】ESFramework介绍之(23)―― AgileTcp
    [转载]ESFramework 4.0 快速上手(15) -- 客户端登录验证
    【转载】ESFramework介绍之(31)―― 消息分类及对应的处理器
    【转载】ESFramework 平台下可复用的Tcp通信层实现
    【转载】ESFramework介绍之(27)-- 支持OverdueMessage (离线消息)
    高性能的大型系统经验 -- 将数据分类、并缓存
    【转载】可复用的FS
  • 原文地址:https://www.cnblogs.com/PureMan6/p/10888890.html
Copyright © 2011-2022 走看看