记一次坑爹的ReactNative应用集成推送

本文记录了在纯ReactNative应用中集成阿里云推送遇到的挑战,包括判断应用启动状态和从原生端向RN传递信息。通过特定代码解决了ReactApplicationContext获取问题,并采用原生方法结合广播确保正确获取ReactContext对象,从而实现推送信息的顺利处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

公司有个需求,实现纯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);
                }

            }

        }
    };
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值