React Js 與 Native 之間的通信

主要內容:

  1. 關於通信的一些思考
  2. React Js 與 Native 之間的通信的三種方式
  3. React Js 與 Native 通信三種方式的比較
  4. 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 方式,採用三種更友好的方式,分別是:

  1. CallBack 方式
  2. Promise 回調
  3. 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 只需要監聽即可。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章