您的位置:首页 > Web前端 > React

React Js 与 Native 之间的通信

2017-06-24 16:35 525 查看
主要内容:

关于通信的一些思考

React Js 与 Native 之间的通信的三种方式

React Js 与 Native 通信三种方式的比较

React Js 与 Native 之间的通信的基本原理

一、关于通信的一些思考

1、进程间的通信:

在Android 系统中,应用是运行在由多个线程组成的进程中的,有的应用包含一个进程,有的可能会有两个进程,甚至多个进程。Android 系统中常见的进程间通信方式有 Binder、AIDL、Messenger;

2、线程间的通信

在Android 中,线程与线程的通信方式有,Intent、Handler;

3、传统的Js 与 Android 之间的通信

场景一般是Andoid WebView 与 页面中加载的Js 方法之间的通信,使用 addJavascriptInterface 来实现两者之间的通信。

比如要实现,在Js 页面中调用 Android 中的 Toast提示,可以这样做:

Java 端:

mWebView.addJavascriptInterface(new WebAppInterface(this), "Android");

public class WebAppInterface {
Context mContext;

/** Instantiate the interface and set the context */
WebAppInterface(Context c) {
mContext = c;
}

// 声明一个@JavascriptInterface,
/** Show a toast from the web page */
@JavascriptInterface
public void showToast(String toast) {
Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
}
}


在 Js 端调用如下:

<button onclick="showAndroidToast('addjavascriptinterface');">showAndroidToast</button>

<script type="text/javascript">
function showAndroidToast(toast) {
Android.showToast(toast);
}
</script>


二、React Js 与 Native 之间的通信的三种方式

在React Js 与 Android 的通信没有使用传统的 addJavascriptInterface 方式,采用三种更友好的方式,分别是:

CallBack 方式

Promise 回调

RCTDeviceEventEmitter 发送消息

1、CallBack 方式

主要的接口说明:

/**
* Interface that represent javascript callback function which can be passed to the native module
* as a method parameter.
*/
public interface Callback {
public void invoke(Object... args);
}


使用方法,在Android 端,在继承ReactContextBaseJavaModule 的子类中,写一个给 JS 返回用户信息的方法:

@ReactMethod
public void callBackTime(String name, Callback callback) {
callback.invoke(name, getDateAndTime());//invoke 的参数是可变长参数;


在JS 端调用和接收回调如下:

<Text style={styles.welcome}
onPress={this.getCallBackTime.bind(this)}
>CallBack 获取时间
</Text>


getCallBackTime() {
NativeModules.CommonModule.callBackTime("Allure",
(msg1, msg2) => {
console.log(msg);
ToastAndroid.show("CallBack收到消息:" + "\n" + msg1 + msg2 , ToastAndroid.SHORT)
}
);
}


2、Promise 回调

在Android 端代码如下:

@ReactMethod
public void getBasicUserInfo(Promise promise){
WritableMap map = Arguments.createMap();
map.putString("user_id", "458");
map.putString("user_name", "jcstest");
map.putString("user_city", "北京");
map.putArray("user_privileges", getPrivilegesWritableArray());
promise.resolve(map);
}


JS端调用如下:

<TouchableHighlight onPress={_getUserInfo.bind(this)}>
<Text> Promise resolve </Text>
</TouchableHighlight>


async function _getUserInfo (){
const _this = this;
try {
ToastAndroid.show("_getUserInfo", ToastAndroid.SHORT);
const data = await NativeModules.CommonModule.getBasicUserInfo()
global.currentUser = data || {};
_this.setState({
userInfo: data,
loading: false
});
ToastAndroid.show(this.state.userInfo.user_city, ToastAndroid.SHORT);
ToastAndroid.show(this.state.userInfo.user_privileges[0], ToastAndroid.SHORT);
} catch (e) {
ToastAndroid.show(e, ToastAndroid.SHORT);
}
}


3、RCTDeviceEventEmitter 发送消息

在Android 代码如下:

public void sendTransMission(ReactContext reactContext, String eventName, @Nullable WritableMap params) {
if(reactContext != null){
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);
}
}


JS 端接收消息代码如下:

componentWillMount() {
this.listener = DeviceEventEmitter.addListener('EventName', function  (msg) {
console.log(msg);
ToastAndroid.show("DeviceEventEmitter收到消息:" + "\n" + msg.turn + "---" + msg.key, ToastAndroid.SHORT)
});
}

componentWillUnmount(){
// 移除
this.listener.remove();
}


三、React Js 与 Native 通信三种方式的比较

CallBack 方式 :

JS 调用,Native 返回;

CallBack 为异步操作,返回时机不确定;

支持可变长参数,回调时参数按顺序取值;

Promise 回调

JS调用,Native返回;

支持多数据类型;

每次使用需要 JS 调用一次

RCTDeviceEventEmitter 事件

由 Native 主动向 JS 发送消息,JS 只需要监听即可。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: