在react-native中能夠經過在java層自定義ReactMethod
(https://segmentfault.com/a/1190000004486024)方式給JavaScript調用,這樣在JavaScript層就能夠直接調用Android中的Native方法.
但在大部分的方法調用中,都須要知道調用方法以後的處理結果是什麼,有沒有出現異常等狀況。JavaScript自己是事件驅動的語言,需在JavaScript中能夠使用回調方法來處理函數返回的結果。一樣地在react-native中定義了Callback
和Promise
的接口,用來處理JavaScript調用Java方法的回調。java
Callback
是react.bridge中的一個接口,它做爲ReactMethod
的一個傳參,用來映射JavaScript的回調函數(function)。Callback
接口只定義了一個方法invoke
,invoke接受多個參數,這個參數必須是react.bridge中支持的參數。
首先咱們定義一個類用來給JavaScript調用:react
public class StoreModule extends ReactContextBaseJavaModule { @Override public String getName() { return "StoreModule"; } }
指定其名稱爲StoreModule。
下面咱們必定個方法,用來保存userName和password到ShardPreferences
中,在這個方法中,咱們須要定義兩個Callback
參數,一個用來處理成功的狀況,一個用來處理異常的狀況。git
@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()); } }
如今咱們有了一個帶有Callback
做爲參數的StoreModule類,把這個類的實例加入ReactPackage
的createNativeModules
中,就能夠在JavaScript層調用該方法。
在JavaScript中,調用這個帶有Callback
參數的方法:github
var {NativeModules}=require('react-native'); var storeModule=NativeModules.StoreModule; storeModule.addUser("jjz","123456",(msg)=>{ alert(msg); },(errorMsg)=>{ alert(errorMsg) });
這裏的方法回調方法咱們都是使用的匿名函數,在JavaScript調用Java以後,處理結果會以Callback
的形式回到JavaScript中,在JavaScript中再對相應的結果進行處理。編程
Promise是ES6
中增長的對於異步編程和回調更加友好的API(https://segmentfault.com/a/1190000004505028),使用Promise能夠更簡潔,更靈活地處理回調。
在react.briage
中定義的Promise
接口,實現了resolve
和reject
的方法,resolve
用來處理正確處理結果的狀況,reject
用來處理異常的狀況。
在StoreModule
定義一個支持Promise
做爲參數的方法:segmentfault
@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中的參數轉換.
調用這個方法的時候,在JavaScript中會返回一個Promise對象,這意味着你能夠JavaScript直接使用。
在JavaScript中調用:react-native
storeModule.login('jjz','123456').then((map)=>{ alert(map['user_id']); },(code,message)=>{ alert(message); })
使用Promise比使用Callback
更加的簡潔,還能更加靈活的在多線程之間進行切換。promise
代碼地址:https://github.com/jjz/react-native/tree/master/RNJava多線程