出處
https://github.com/crazycodeboy/RNStudyNotes/tree/master/React%20Native%E5%8E%9F%E7%94%9F%E6%A8%A1%E5%9D%97%E5%90%91JS%E4%BC%A0%E9%80%92%E6%95%B0%E6%8D%AE%E7%9A%84%E5%87%A0%E7%A7%8D%E6%96%B9%E5%BC%8F
有時(shí)需要在native和js之間傳遞數(shù)據(jù),有以下幾種方式
Callback
Callback是最常用的設(shè)計(jì)模式之一。無論是java,oc,c#,還是js等都會(huì)看到Callback的身影;
native支持Callback類型的參數(shù),該Callback對(duì)應(yīng)js中的function。
- 寫法
//native部分
public class EasyKitModule extends ReactContextBaseJavaModule {
private static final String TAG = EasyKitModule.class.getSimpleName();
public EasyKitModule(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return "EasyKit";
}
@ReactMethod//三個(gè)參數(shù)分別對(duì)應(yīng) js向native傳的參數(shù)、js失敗回調(diào)方法、js成功回調(diào)方法
public void runWithCallback(String params, Callback errorCallback, Callback successCallback) {
Log.i(TAG + "_params:", params);
try {
successCallback.invoke(getResult());//通過invoke方法將數(shù)據(jù)返回給js
} catch (Exception e) {
errorCallback.invoke(e.getMessage());
}
}
...
}
//js部分
export default class Tab1 extends BaseComponent {
_onPress = () => {
this._invokeNativeWithCallback()
}
_invokeNativeWithCallback = () => {
let greetFromJS = 'hello,it is from reactjs'
const errCallback = (errCode, errMsg) => {
console.log(errCode, errMsg)
}
const successCallback = (data) => {
console.log(data)
}
EasyKit.runWithCallback(//這里的三個(gè)參數(shù)與原生模塊中的方法相對(duì)應(yīng)
greetFromJS,
errCallback,
successCallback,
)
}
...
}
Promise
Promises是es6的一個(gè)新的特性,在rn中非常重要。native也支持Promise。
- 寫法
//native部分
@ReactMethod//接收參數(shù)對(duì)應(yīng)js向native傳遞的參數(shù),js中的Promise容器
public void runWithPromise(String params, Promise promise) {
Log.i(TAG + "_params:", params);
try {
int a = 10 / 0;
promise.resolve(getResult());
} catch (Exception e) {
promise.reject(TAG, e.getMessage());
}
}
//js部分
_invokeNativeWithPromise = () => {
let greetFromJS = 'hello,it is from reactjs'
new Promise((resolve, reject) => {
const result = EasyKit.runWithPromise(greetFromJS)//這里調(diào)用native方法的時(shí)只需傳前面的參數(shù)
resolve(result)
}).then((result) => {
console.log(result)
}).catch((error) => {
console.log(error)
})
}
Event
native支持以事件的方式向js發(fā)送數(shù)據(jù),像Android中的廣播,iOS中的通知中心;接收方注冊(cè)接收該事件即可接收到native發(fā)送的事件。
- 寫法
這里通過js調(diào)用native方法來發(fā)送事件
//native部分
@ReactMethod
public void sendEventFromNative(String params) {
WritableMap map = Arguments.createMap();
map.putString("nativeMsg", "hello,it is a global event from native");
sendEvent(getReactApplicationContext(), "wishesFromNative", map);
}
private void sendEvent(ReactContext reactContext, String eventName, @Nullable WritableMap params) {
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);//發(fā)送的事件包括事件名和需要傳遞的數(shù)據(jù)
}
//js部分
_sendEventFromNative = () => {
let greetFromJS = 'hello,it is from reactjs'
//觸發(fā)native發(fā)送事件
EasyKit.sendEventFromNative(greetFromJS)
}
//定義事件處理方法
_handleNativeEvent = (data) => {
console.log('tab_1 receives a native event', data)
}
componentDidMount() {
//這里需要先添加事件監(jiān)聽 參數(shù)分別為 時(shí)間名、事件處理方法
DeviceEventEmitter.addListener('wishesFromNative', this._handleNativeEvent)
}
componentWillUnmount() {
//當(dāng)必要時(shí) 可注銷監(jiān)聽事件
DeviceEventEmitter.removeListener('wishesFromNative')
}
方式對(duì)比
| 類型 | 缺點(diǎn) | 優(yōu)點(diǎn) |
|---|---|---|
| Callback | 單次傳遞 | 傳遞過程可控 |
| Promise | 單次傳遞 | 傳遞過程可控 |
| Event | native驅(qū)動(dòng),js被動(dòng)接收 | 可多端接收 |