在react native中會涉及到不少頁面之間的參數傳遞問題。靜態的參數傳遞一般利用組件的Props屬性,在初始化組件時便可從父組件中將參數傳遞到子組件中。對於非父子關係的組件來講,沒法直接傳遞參數,此時可能會用到react-navigation來傳遞;此外,若要將異步函數、不可預料的事件執行等獲得的參數用於頁面刷新時,前述的方法都不太奏效。react
react-native中採用了DeviceEventEmitter來實現對事件的監聽,實現非父子關係的頁面之間的通訊。具體來講,咱們能夠在一個頁面中經過DeviceEventEmitter來對特定名稱的事件進行監聽,此後每當其它位置發送該名稱的事件,都會觸發這個監聽的響應並執行對應的函數。android
DeviceEventEmitter優勢在於一次註冊屢次響應,而且註冊後的監聽事件是全局性的。不只如此,經過DeviceEventEmitter還能夠與原生模塊進行交互。react-native
首先要引入DeviceEventEmitter,DeviceEventEmitter在原生庫中,直接引入便可:異步
import { DeviceEventEmitter } from 'react-native';
一般來講咱們會在組件加載完成後開始監聽事件:ide
componentDidMount(){ this.emitter = DeviceEventEmitter.addListener('eventName’, function); };
addListener('eventName’, function);
擁有兩個參數,第一個參數是監聽事件的名稱,爲字符串類型;第二個參數是觸發監聽事件後的回調函數。函數
註冊監聽後,咱們能夠在任意位置直接使用DeviceEventEmitter.emit('eventName',params)
來廣播一個事件。該函數也有兩個參數。第一個參數一樣爲事件名稱;第二個參數爲可選項,用於參數的傳遞。this
當頁面卸載時,卸載監聽事件:code
componentWillUnmount() { this.emitter.remove() }
只須要在原生模塊中廣播該事件便可。具體代碼以下:component
private void sendEvent(ReactContext reactContext,String eventName, @Nullable WritableMap params) { reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) .emit(eventName, params); }
上述代碼發送了一個名爲eventName的包含params參數的事件,值得注意的是發送該事件的前提是react native環境已經加載完成,須要獲取其上下文ReactContext。事件
react native沒法直接監聽廣播事件,所以須要用到原生模塊協助。此處經過兩次監聽事件,採用安卓原生廣播+安卓與react native通訊來實現react native對通知消息點擊事件的響應。
第一步採用經過安卓原生模塊監聽通知點擊事件(參見安卓廣播機制)並獲取到通知攜帶的參數信息。
public static class NotificationReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if(intent.getAction().equals("androidNotification")){//響應通知事件 String params = intent.getExtras().getString("params"); if(params != null){ sendEventToRn("RNnotification",params);//發送事件給RN } } } } public static void sendEventToRn(String eventName, @Nullable String params){ //這裏的模塊中context已經獲取 context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) .emit("notification", params); }
'RNnotification','androidNotification'爲靜態註冊的廣播接收器。廣播的發送須要在通知消息的設置處自定義。本項目中處理過程以下:
Intent intent =new Intent(); intent.setAction("androidNotification"); intent.putExtra("params",msg.getRaw().toString()); Activity currentActivity = MainActivity.getCurrentActivity();//這裏獲取的是當前activity currentActivity.sendBroadcast(intent);
而後在react native中監聽通知事件'RNnotification'
DeviceEventEmitter.addListener('notification',this.notification); console.log('開始監聽通知'); notification = (paramString) =>{ //...此處實現了根據參數導航到指定頁面 }
大功告成。