在react-native中可以通過在java層自定義ReactMethod
(http://www.itdecent.cn/p/93dfbbdd9255)方式給JavaScript調(diào)用,這樣在JavaScript層就可以直接調(diào)用Android中的Native方法.
但在大部分的方法調(diào)用中,都需要知道調(diào)用方法之后的處理結(jié)果是什么,有沒有出現(xiàn)異常等情況。JavaScript本身是事件驅(qū)動的語言,需在JavaScript中可以使用回調(diào)方法來處理函數(shù)返回的結(jié)果。同樣地在react-native中定義了Callback和Promise的接口,用來處理JavaScript調(diào)用Java方法的回調(diào)。
Callback
Callback是react.bridge中的一個(gè)接口,它作為ReactMethod的一個(gè)傳參,用來映射JavaScript的回調(diào)函數(shù)(function)。Callback接口只定義了一個(gè)方法invoke,invoke接受多個(gè)參數(shù),這個(gè)參數(shù)必須是react.bridge中支持的參數(shù)。
首先我們定義一個(gè)類用來給JavaScript調(diào)用:
public class StoreModule extends ReactContextBaseJavaModule {
@Override
public String getName() {
return "StoreModule";
}
}
指定其名稱為StoreModule。
下面我們一定個(gè)方法,用來保存userName和password到ShardPreferences中,在這個(gè)方法中,我們需要定義兩個(gè)Callback參數(shù),一個(gè)用來處理成功的情況,一個(gè)用來處理異常的情況。
@ReactMethod
public void addUser(String userName, String password, Callback successCallback, Callback errorCallback) {
try {
if (TextUtils.isEmpty(userName)) {
errorCallback.invoke("user name is empty");
return;
}
if (TextUtils.isEmpty(password)) {
errorCallback.invoke("password is empty");
return;
}
preferences.edit().putString(USER_NAME, userName).commit();
preferences.edit().putString(PASSWORD, password).commit();
successCallback.invoke("add user success");
} catch (Exception e) {
e.printStackTrace();
errorCallback.invoke(e.getMessage());
}
}
現(xiàn)在我們有了一個(gè)帶有Callback作為參數(shù)的StoreModule類,把這個(gè)類的實(shí)例加入ReactPackage的createNativeModules中,就可以在JavaScript層調(diào)用該方法。
在JavaScript中,調(diào)用這個(gè)帶有Callback參數(shù)的方法:
var {NativeModules}=require('react-native');
var storeModule=NativeModules.StoreModule;
storeModule.addUser("jjz","123456",(msg)=>{
alert(msg);
},(errorMsg)=>{
alert(errorMsg)
});
這里的方法回調(diào)方法我們都是使用的匿名函數(shù),在JavaScript調(diào)用Java之后,處理結(jié)果會以Callback的形式回到JavaScript中,在JavaScript中再對相應(yīng)的結(jié)果進(jìn)行處理。
Promise
Promise是ES6中增加的對于異步編程和回調(diào)更加友好的API(http://www.itdecent.cn/p/ff4118094b2c),使用Promise可以更簡潔,更靈活地處理回調(diào)。
在react.briage中定義的Promise接口,實(shí)現(xiàn)了resolve和reject的方法,resolve用來處理正確處理結(jié)果的情況,reject用來處理異常的情況。
在StoreModule定義一個(gè)支持Promise作為參數(shù)的方法:
@ReactMethod
public void login(String userName, String password, Promise promise) {
String storeUserName = preferences.getString(USER_NAME, "");
String storePassword = preferences.getString(PASSWORD, "");
if (!equalsString(userName, storeUserName)) {
promise.reject("0", "user name is wrong");
return;
}
if (!equalsString(password, storePassword)) {
promise.reject("1", "password is wrong");
return;
}
WritableMap map = Arguments.createMap();
map.putDouble("user_id", 1);
promise.resolve(map);
}
這里的WritableMap繼承了ReadableMap,定義了Java和JavaScript中的參數(shù)轉(zhuǎn)換.
調(diào)用這個(gè)方法的時(shí)候,在JavaScript中會返回一個(gè)Promise對象,這意味著你可以JavaScript直接使用。
在JavaScript中調(diào)用:
storeModule.login('jjz','123456').then((map)=>{
alert(map['user_id']);
},(code,message)=>{
alert(message);
})
使用Promise比使用Callback更加的簡潔,還能更加靈活的在多線程之間進(jìn)行切換。
代碼地址:https://github.com/jjz/react-native/tree/master/RNAndroid