React-Native 與原生的3種互動通訊(Android)
前言
最近到新公司,採用React-Native開發App。在某些效能方面有問題或者模組特殊的開發情況,不可避免的需要我們原生開發(Android\IOS)給予前端開發支援。
在為前端書寫模組部分,不可避免的要接觸核心的通訊部分。
大致分為2種情況:
Android主動向JS端傳遞事件、資料
JS端被動向Android詢問獲取事件、資料
方式 | 優點 | 缺點 |
---|---|---|
事件方式:RCTDeviceEventEmitter | 可任意時刻傳遞,Native主導控制 | 個人覺得此種方式缺點小 |
CallBack回撥方式 | JS呼叫一次,Native返回一次 | CallBack為非同步操作,返回時機不確定 |
Promises 方式 | JS呼叫一次,Native返回一次 | 每次使用需要JS呼叫一次 |
效果圖:
①:Android向JS傳遞事件
採用RCTDeviceEventEmitter:
在Native模組:
//延遲0.1秒獲取時間。
@ReactMethod
public void getTime() {
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(100 );
} catch (InterruptedException e) {
e.printStackTrace();
}
SimpleDateFormat formatDate = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
Date date = new Date(System.currentTimeMillis());
String time = formatDate.format(date);
WritableMap writableMap = new WritableNativeMap();
writableMap.putString("key", time);
sendTransMisson(mReactContext, "EventName", writableMap);
}
}).start();
}
/**
* @param reactContext
* @param eventName 事件名
* @param params 傳慘
*/
public void sendTransMisson(ReactContext reactContext, String eventName, @Nullable WritableMap params) {
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);
}
getTime()主要為JS端呼叫Native的方法,在內部呼叫
sendTransMisson進行事件傳送。 sendTransMisso這個方法名可以任意取
你喜歡就好,內部引數eventName為事件名,params為傳遞的事件屬性。
在JS端接受:
componentWillMount() {
DeviceEventEmitter.addListener('EventName', function (msg) {
console.log(msg);
ToastAndroid.show("DeviceEventEmitter收到訊息:" + "\n" + msg.key, ToastAndroid.SHORT)
});
}
在componentWillMount進行監聽事件獲取傳遞的事件資訊。
②:JS被動向Android詢問事件、資訊
- CallBack回撥接受:
Native部分:
@ReactMethod
public void callBackTime(String name,Callback callback){
callback.invoke(getTimeMillis());
}
CallBack對應的就是JS中的function,JS呼叫Native模組處理完畢以後將時間回撥給JS端。
JS端傳送:
getCallBackTime() {
NativeModules.TransMissonMoudle.callBackTime("Allure",
(msg) => {
console.log(msg);
ToastAndroid.show("CallBack收到訊息:"+msg,ToastAndroid.SHORT)
}
);
}
向Native傳送了一個名字Allure,在第二個引數接收回調結果。
Callback通俗簡單易懂。
- Promise傳遞
promise在js中很常見,而android也有類似的就是RxJava.可以通過鏈式將複雜程式碼結構轉換為簡短易讀的程式碼。
由於promise不確定成功與失敗,需要同步狀態。 一般會呼叫then介面。
Native端:
@ReactMethod
public void sendPromiseTime(String name, Promise promise) {
WritableMap writableMap=new WritableNativeMap();
writableMap.putString("age","20");
writableMap.putString("time",getTimeMillis());
promise.resolve(writableMap);
}
在此方法,接受了一個JS端傳來的name,並且回傳給JS端了一個字典,並存儲了age和time兩個欄位。 需要注意的是使用Promise時,Promise引數需要放在最後一個引數裡,否則JS接搜不到訊息。
JS端:
getPromiseTime() {
NativeModules.TransMissonMoudle.sendPromiseTime("Allure").then(msg=> {
console.log("年齡:" + msg.age + "/n" + "時間:" + msg.time);
ToastAndroid.show("Promise收到訊息:" + "\n" + "年齡:" + msg.age + "時間:" + msg.time, ToastAndroid.SHORT)
this.setState({
age: msg.age,
time: msg.time,
})
}).catch(error=> {
console.log(error);
});
}
JS端通過then介面來獲取Promise的資料。
至此,JS與Native的三種通訊方式就此結束,不知道各位是否讀懂了呢? 若有疑問可以留言私信均可。
注意在專案主目錄先npm install。