React Native之Android原生通过DeviceEventEmitter发送消息给js

简介: React Native之Android原生通过DeviceEventEmitter发送消息给js

1 问题

Android原生向js发消息,并且可以携带数据

2 实现原理

Android原生可以使用RCTEventEmitter来注册事件,然后这里需要指定事件的名字,然后在js那端进行监听同样事件的名字监听,就可以收到消息得到数据

reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(eventName, params);

这里的eventName和下面的'EventName'的值需要保持一致.

js那端的监听

   componentWillMount(){  
      //监听事件名为EventName的事件
      DeviceEventEmitter.addListener('EventName', function() {  
          alert("Android send js msg success");  
      });                                
    }

3 代码实现

可以先参考我前面几篇博客的部分代码和类文件

React Native实现js调用安卓原生代码

React Native之js调用Android原生使用Callback传递结果给js

还是基于上面的文章,然后我这边多加了一个Test.java类,文件如下,这里主要是注册

package com.pro_react;
import android.content.Context;
import android.provider.Settings;
import android.support.annotation.Nullable;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
public class Test {
    //定义上下文对象
    public ReactContext myContext;
    public Test(ReactContext context) {
        this.myContext = context;
    }
    //定义发送事件的函数
    public void sendEventToUi(ReactContext reactContext, String eventName, @Nullable WritableMap params) {
        reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(eventName, params);
    }
    public void sendMsg()
    {
        //在该方法中开启线程,并且延迟1秒,然后向JavaScript端发送事件。
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //发送事件,事件名为EventName
                WritableMap wm = Arguments.createMap();
                sendEventToUi(myContext,"EventName", wm);
            }
        }).start();
    }
}

然后在MyToastModule.java文件里面增加了,当js点击文本触发showMyName函数的时候,我们这边就向js发送消息,MyToastModule.java文件如下

package com.pro_react;
import android.content.Context;
import android.util.Log;
import android.widget.Toast;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
/**
 * Created by chenyu on 9/15/18.
 */
public class MyToastModule extends ReactContextBaseJavaModule {
    public ReactContext mContext;
    public MyToastModule(ReactApplicationContext reactContext) {
        super(reactContext);
        mContext = reactContext;
    }
    /**
     * getName方法返回一个字符串名字,就是js中的模块名
     * 到时候我们写js的时候需要导入这个模块,这里我用的是MyToast
     */
    @Override
    public String getName() {
        return "MyToast";
    }
    /**
     * 这是js调用的方法,需要使用注解@ReactMethod,返回类型必须为void
     */
    @ReactMethod
    public void show() {
        Toast.makeText(getReactApplicationContext(), "I am chenyu", Toast.LENGTH_SHORT).show();
    }
    @ReactMethod(isBlockingSynchronousMethod = true)
    public String showMyName() {
        NotificationUtil util = NotificationUtil.getInstance(mContext);
        //util.showMessage();
        //向ui发送消息
        new Test(mContext).sendMsg();
        return "chenyu1";
    }
}

App.js文件修改如下

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow
 */
import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View, NativeModules, DeviceEventEmitter} from 'react-native';
const instructions = Platform.select({
  ios: 'Press Cmd+R to reload,\n' + 'Cmd+D or shake for dev menu',
  android:
    'Double tap R on your keyboard to reload,\n' +
    'Shake or press menu button for dev menu',
});
var myAndroidToast = NativeModules.MyToast;
type Props = {};
export default class App extends Component<Props> {
   componentWillMount(){  
      //监听事件名为EventName的事件
      DeviceEventEmitter.addListener('EventName', function() {  
          alert("Android send js msg success");  
      });                                
    }
    constructor(props){
        super(props);
        this.state={
            myName:'chenzixuan',
        }
    }
  render() {
    return (
      <View style={styles.container}>
        <Text onPress={()=> this._androidShowMsg()} style={styles.welcome}>Welcome to React Native!</Text>
        <Text style={styles.instructions}>To get started, edit App.js</Text>
        <Text style={styles.instructions}>{instructions}</Text>
        <Text style={styles.instructions}>{this.state.myName}</Text>
      </View>
    );
  }
    _androidShowMsg = () => {
       var value = myAndroidToast.showMyName();
       this.setState({myName:value});
    };
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

4 测试结果

这里修改了App.js,所以需要新生成android.index.bundle文件,执行命令如下

react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res

然后再执行

react-native run-android

20170724223902569.png点击Welcome to React Native效果如下

20170724223902569.png



相关文章
|
15小时前
|
开发框架 移动开发 前端开发
【Uniapp 专栏】Uniapp 与 React Native 的对比分析
【5月更文挑战第14天】Uniapp和React Native是热门的跨平台移动开发框架。Uniapp以其一套代码多端运行、丰富的组件生态和较低的学习曲线受到青睐,适合快速开发简单应用。React Native基于React,拥有活跃社区和优秀性能,适合复杂应用。React Native在性能上略胜一筹,尤其在需要接近原生体验的场景。Uniapp的官方组件弥补了社区资源不足。选择时需考虑开发效率、性能需求、团队技术栈和社区支持。
【Uniapp 专栏】Uniapp 与 React Native 的对比分析
|
1天前
|
移动开发 前端开发 JavaScript
使用React Native进行跨平台移动开发
【5月更文挑战第13天】React Native是Facebook的跨平台移动开发框架,基于JavaScript和React,允许开发者编写原生应用。它提供跨平台性、原生性能、平缓的学习曲线及丰富的社区支持。开发流程包括安装CLI、创建项目、编写代码、运行调试及测试发布。进阶应用涉及状态管理、性能优化、原生模块集成和自动化测试。React Native降低了开发成本,提升了效率,是移动开发的优选方案。
|
5天前
|
JavaScript 计算机视觉
原生js通过年龄判断是否可以抽奖
原生js通过年龄判断是否可以抽奖
10 0
|
6天前
|
存储 JavaScript 前端开发
原生JS如何实现验证码
原生JS如何实现验证码
11 0
|
6天前
|
JavaScript 安全 前端开发
原生JS实现一键复制,一键粘贴
原生JS实现一键复制,一键粘贴
11 0
|
14天前
|
开发框架 Dart 前端开发
【Flutter前端技术开发专栏】Flutter与React Native的对比与选择
【4月更文挑战第30天】对比 Flutter(Dart,强类型,Google支持,快速热重载,高性能渲染)与 React Native(JavaScript,庞大生态,热重载,依赖原生渲染),文章讨论了开发语言、生态系统、性能、开发体验、学习曲线、社区支持及项目选择因素。两者各有优势,选择取决于项目需求、团队技能和长期维护考虑。参考文献包括官方文档和性能比较文章。
【Flutter前端技术开发专栏】Flutter与React Native的对比与选择
|
16天前
|
SQL 存储 前端开发
React&Nest.js全栈社区平台(五)——👋封装通用分页Service实现文章流与详情
React&Nest.js全栈社区平台(五)——👋封装通用分页Service实现文章流与详情
React&Nest.js全栈社区平台(五)——👋封装通用分页Service实现文章流与详情
|
16天前
|
存储 SQL 前端开发
React&Nest.js社区平台(四)——✏️文章发布与管理实战
React&Nest.js社区平台(四)——✏️文章发布与管理实战
|
16天前
|
存储 前端开发 API
React&Nest.js全栈社区平台(三)——🐘对象存储是什么?为什么要用它?
React&Nest.js全栈社区平台(三)——🐘对象存储是什么?为什么要用它?
|
16天前
|
存储 前端开发 中间件
切图仔做全栈:React&Nest.js社区平台(二)——👋手把手实现优雅的鉴权机制
切图仔做全栈:React&Nest.js社区平台(二)——👋手把手实现优雅的鉴权机制