公司有個需求,實現純RN應用的接收推送後的界面跳轉,推送使用的是阿里雲推送
坑的地方至少有兩個。
如何知道應用是否已經啓動了呢?
如何將信息發送給RN端呢?
首先第一個問題相對來說還是比較好解決的,用下面的代碼就可以實現。
親測可行
private boolean _isApplicationRunning(Context context) {
ActivityManager activityManager = (ActivityManager) context.getApplicationContext().getSystemService(context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> processInfos = activityManager.getRunningAppProcesses();
for (ActivityManager.RunningAppProcessInfo processInfo : processInfos) {
if (processInfo.processName.equals(context.getApplicationContext().getPackageName())) {
if (processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
for (String d: processInfo.pkgList) {
return true;
}
}
}
}
return false;
}
第二個問題,傳遞的話最好肯定是原生端主動發請求給JS,讓js去處理請求。
想到的是DeviceEventEmitter,但是網上的大多數代碼都是講這個方法嵌套在ReactContextBaseJavaModule的子類中運行的,在外面獲取不到必要的參數
ReactApplicationContext
最後看到一句代碼
ReactContext reactContext = getReactInstanceManager().getCurrentReactContext();
這句話可以正常返回ReactContext’對象,但是在不合適的時候拿到的對象會是空值。
想到了一個比較蠢的方法,寫一個原生方法,如果react界面已經初始化完成,就發送廣播,MainActivity獲取廣播,在這時在去獲取ReactContext對象,這樣就能獲取到正確的ReactContext對象,並且保證不爲空。
原生方法代碼
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;
import com.alibaba.sdk.android.push.CloudPushService;
import com.alibaba.sdk.android.push.noonesdk.PushServiceFactory;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
/**
* Created by user on 2017/5/2.
*/
public class AlreadyLoding extends ReactContextBaseJavaModule{
Context context;
private static final String TAG = "AlreadyLoding";
public AlreadyLoding(ReactApplicationContext reactContext) {
super(reactContext);
this.context = reactContext;
}
@Override
public String getName() {
return "alreadyloding";
}
/**
* 當RN端加載完畢發送廣播通知原聲端
*
*/
@ReactMethod
public void haveLoding() {
Log.e(TAG,"廣播發送成功");
Intent intent = new Intent();
intent.setAction("com.alreadyLoding"); //設置Action
intent.putExtra("msg", "接收動態註冊廣播成功!"); //添加附加信息
context.sendBroadcast(intent);
}
}
MainActivity界面
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.widget.Toast;
import com.cboy.rn.splashscreen.SplashScreen;
import com.facebook.react.ReactActivity;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import javax.annotation.Nullable;
import cn.hlgcb.adtool.modules.push.Push;
public class MainActivity extends ReactActivity {
ReactContext reactcontext;
String title = "Login";
String jumpTo;
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
SplashScreen.show(this); // here
super.onCreate(savedInstanceState);
IntentFilter dynamic_filter = new IntentFilter();
dynamic_filter.addAction("com.alreadyLoding"); //添加動態廣播的Action
registerReceiver(myReceiver, dynamic_filter); // 註冊自定義動態廣播消息
Intent intent = getIntent(); //接受廣播傳入的信息
if(intent!=null){
jumpTo=intent.getStringExtra("extraMap");
}
}
@Override
protected void onResume() {
super.onResume();
}
/**
* Returns the name of the main component registered from JavaScript.
* This is used to schedule rendering of the component.
*/
@Override
protected String getMainComponentName() {
return "wanghongADToolTrunk";
}
public static void sendEvent(ReactContext reactContext, String eventName, String params) {
System.out.println("reactContext=" + reactContext);
Log.e("aaaa", "我執行了");
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);
}
/**
*
* 廣播
* 如果收到已經加載完成的信息並且收到了推送信息就跳轉
*/
private BroadcastReceiver myReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("com.alreadyLoding")) { //動作檢測
String msg = intent.getStringExtra("msg");
ReactContext reactContext = getReactInstanceManager().getCurrentReactContext();
if(jumpTo!=null){
sendEvent(reactContext, "push", jumpTo);
}
}
}
};
}