首页 > 解决方案 > 在自定义广播接收器中从推送通知打开时反应本机应用程序崩溃

问题描述

我刚刚构建了一个用于向 React Native 发送事件的原生模块,所需的效果是接收通过 Braze 发送的推送通知,在 react native 中剥离深层链接以适当地路由我的应用程序。如果应用程序是后台的,这很有效,但如果它被关闭,它将导致崩溃并在 Logcat 中出现以下错误:

10-02 15:11:34.888 20942-20942/com.my.app E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.my.app, PID: 20942
    java.lang.RuntimeException: Unable to start receiver com.my.app.AppboyBroadcastReceiver: java.lang.NullPointerException: Attempt to invoke virtual method 'com.facebook.react.bridge.JavaScriptModule com.facebook.react.bridge.ReactApplicationContext.getJSModule(java.lang.Class)' on a null object reference
        at android.app.ActivityThread.handleReceiver(ActivityThread.java:3259)
        at android.app.ActivityThread.-wrap17(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1677)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6541)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'com.facebook.react.bridge.JavaScriptModule com.facebook.react.bridge.ReactApplicationContext.getJSModule(java.lang.Class)' on a null object reference
        at com.my.app.AppboyNotification.sendEvent(AppboyNotification.java:36)
        at com.my.app.AppboyBroadcastReceiver.onReceive(AppboyBroadcastReceiver.java:42)
        at android.app.ActivityThread.handleReceiver(ActivityThread.java:3252)

我假设这是因为应用程序尚未正确启动并且它已经在尝试触发它不应该触发的东西。我的广播接收器看起来像这样,在哪里notificationOpenedAction.equals(action)调用:

public class AppboyBroadcastReceiver extends BroadcastReceiver{
    private static final String TAG = AppboyLogger.getAppboyLogTag(AppboyBroadcastReceiver.class);

    @Override
    public void onReceive(Context context, Intent intent) {
        String packageName = context.getPackageName();
        String pushReceivedAction = packageName + AppboyNotificationUtils.APPBOY_NOTIFICATION_RECEIVED_SUFFIX;
        String notificationOpenedAction = packageName + AppboyNotificationUtils.APPBOY_NOTIFICATION_OPENED_SUFFIX;
        String notificationDeletedAction = packageName + AppboyNotificationUtils.APPBOY_NOTIFICATION_DELETED_SUFFIX;

        String action = intent.getAction();
        Log.d(TAG, String.format("Received intent with action %s", action));

        logNotificationDuration(intent);

        if (pushReceivedAction.equals(action)) {
            Log.d(TAG, "Received push notification.");
        } else if (notificationOpenedAction.equals(action)) {
            String deepLink = intent.getStringExtra(Constants.APPBOY_PUSH_DEEP_LINK_KEY);
            WritableNativeMap params = new WritableNativeMap();

            params.putString("appboyDeeplink", deepLink);

            Log.d(TAG, "Received push open action notification.");
            Log.d(TAG, String.format("DeeplinkData: %s", deepLink));

            AppboyNotification.sendEvent("appboyNotificationReceived", params);
        } else if (notificationDeletedAction.equals(action)) {
            Log.d(TAG, "Received push notification deleted intent.");
        } else {
            Log.d(TAG, String.format("Ignoring intent with unsupported action %s", action));
        }
    }

我的 ActivityEventListener 如下:

public class AppboyNotification extends ReactContextBaseJavaModule implements ActivityEventListener{
    private static final String TAG = "AppboyMessaging";
    private static ReactApplicationContext reactContext;
    private String thisApp;


    public AppboyNotification(ReactApplicationContext reactContext){
        super(reactContext);

        this.reactContext = reactContext;
        Log.d(TAG, String.format("React_context %s", reactContext));
        reactContext.addActivityEventListener(this);

        thisApp = reactContext.getPackageName();
    }

    @Override
    public String getName() {
        return TAG;
    }

    public static void sendEvent(String event, WritableNativeMap params) {
        reactContext
                .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                .emit(event, params);
    }

    @Override
    public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {}

    @Override
    public void onNewIntent(Intent intent){}
}

还有我的包文件:

public class AppboyMessaging implements ReactPackage {

    @Override
    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
        List<NativeModule> modules = new ArrayList<>();
        modules.add(new AppboyNotification(reactContext));

        return modules;
    }


    public List<Class<? extends JavaScriptModule>> createJSModules() {
        return Collections.emptyList();
    }

    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }
}

有什么方法可以避免这个错误,并优雅地处理这个错误,所以当我从推送通知打开时,我仍然可以获得我需要的数据?

标签: androidreact-nativepush-notificationbroadcastreceiverreact-native-native-module

解决方案


推荐阅读