React Native之Android原生通過(guò)DeviceEventEmitter發(fā)送消息給js
1 問(wèn)題
Android原生向js發(fā)消息,并且可以攜帶數(shù)據(jù)
2 實(shí)現(xiàn)原理
Android原生可以使用RCTEventEmitter來(lái)注冊(cè)事件,然后這里需要指定事件的名字,然后在js那端進(jìn)行監(jiān)聽(tīng)同樣事件的名字監(jiān)聽(tīng),就可以收到消息得到數(shù)據(jù)
Android注冊(cè)關(guān)鍵代碼
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(eventName, params);
這里的eventName和下面的'EventName'的值需要保持一致.
js那端的監(jiān)聽(tīng)
componentWillMount(){
//監(jiān)聽(tīng)事件名為EventName的事件
DeviceEventEmitter.addListener('EventName', function() {
alert("Android send js msg success");
});
}
3 代碼實(shí)現(xiàn)
可以先參考我前面幾篇博客的部分代碼和類(lèi)文件
React Native實(shí)現(xiàn)js調(diào)用安卓原生代碼
React Native之js調(diào)用Android原生使用Callback傳遞結(jié)果給js
還是基于上面的文章,然后我這邊多加了一個(gè)Test.java類(lèi),文件如下,這里主要是注冊(cè)
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 {
//定義上下文對(duì)象
public ReactContext myContext;
public Test(ReactContext context) {
this.myContext = context;
}
//定義發(fā)送事件的函數(shù)
public void sendEventToUi(ReactContext reactContext, String eventName, @Nullable WritableMap params) {
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(eventName, params);
}
public void sendMsg()
{
//在該方法中開(kāi)啟線程,并且延遲1秒,然后向JavaScript端發(fā)送事件。
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//發(fā)送事件,事件名為EventName
WritableMap wm = Arguments.createMap();
sendEventToUi(myContext,"EventName", wm);
}
}).start();
}
}
然后在MyToastModule.java文件里面增加了,當(dāng)js點(diǎn)擊文本觸發(fā)showMyName函數(shù)的時(shí)候,我們這邊就向js發(fā)送消息,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方法返回一個(gè)字符串名字,就是js中的模塊名
* 到時(shí)候我們寫(xiě)js的時(shí)候需要導(dǎo)入這個(gè)模塊,這里我用的是MyToast
*/
@Override
public String getName() {
return "MyToast";
}
/**
* 這是js調(diào)用的方法,需要使用注解@ReactMethod,返回類(lèi)型必須為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發(fā)送消息
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(){
//監(jiān)聽(tīng)事件名為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 測(cè)試結(jié)果
這里修改了App.js,所以需要新生成android.index.bundle文件,執(zhí)行命令如下
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
然后再執(zhí)行
react-native run-android
效果如下
點(diǎn)擊Welcome to React Native效果如下
作者:chen.yu
深信服三年半工作經(jīng)驗(yàn),目前就職游戲廠商,希望能和大家交流和學(xué)習(xí),
微信公眾號(hào):編程入門(mén)到禿頭 或掃描下面二維碼
零基礎(chǔ)入門(mén)進(jìn)階人工智能(鏈接)