android - 注销 BroadcastReceiver

标签 android broadcastreceiver android-service onstart

在我的应用程序中,我有一个将 BroadcastReceiver 注册到 onStart() 方法中的服务:

public void onStart() {
    if(something....) {
        IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
        filter.addAction(Intent.ACTION_SCREEN_OFF);
        screenReceiver = new ScreenReceiver();
        registerReceiver(screenReceiver, filter);
    } else {
        if(screenReceiver != null) {
            unregisterReceiver(screenReceiver);
        }
    }
}

并且它工作正常。 但是我会在 else 中注销这个 BroadcastReceiver,然后我收到这个错误:

01-25 09:30:03.730: ERROR/AndroidRuntime(11748): FATAL EXCEPTION: main
01-25 09:30:03.730: ERROR/AndroidRuntime(11748): java.lang.RuntimeException: Unable to start service com.myservice.Service@460ce7d8 with Intent { cmp=com.myservice/.Service (has extras) }: java.lang.IllegalArgumentException: Receiver not registered: com.myreceiver.ScreenReceiver@46079370
01-25 09:30:03.730: ERROR/AndroidRuntime(11748):     at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3063)
01-25 09:30:03.730: ERROR/AndroidRuntime(11748):     at android.app.ActivityThread.access$3600(ActivityThread.java:125)
01-25 09:30:03.730: ERROR/AndroidRuntime(11748):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2096)
01-25 09:30:03.730: ERROR/AndroidRuntime(11748):     at android.os.Handler.dispatchMessage(Handler.java:99)
01-25 09:30:03.730: ERROR/AndroidRuntime(11748):     at android.os.Looper.loop(Looper.java:123)
01-25 09:30:03.730: ERROR/AndroidRuntime(11748):     at android.app.ActivityThread.main(ActivityThread.java:4627)
01-25 09:30:03.730: ERROR/AndroidRuntime(11748):     at java.lang.reflect.Method.invokeNative(Native Method)
01-25 09:30:03.730: ERROR/AndroidRuntime(11748):     at java.lang.reflect.Method.invoke(Method.java:521)
01-25 09:30:03.730: ERROR/AndroidRuntime(11748):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
01-25 09:30:03.730: ERROR/AndroidRuntime(11748):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
01-25 09:30:03.730: ERROR/AndroidRuntime(11748):     at dalvik.system.NativeStart.main(Native Method)
01-25 09:30:03.730: ERROR/AndroidRuntime(11748): Caused by: java.lang.IllegalArgumentException: Receiver not registered: com.myreceiver.ScreenReceiver@46079370
01-25 09:30:03.730: ERROR/AndroidRuntime(11748):     at android.app.ActivityThread$PackageInfo.forgetReceiverDispatcher(ActivityThread.java:793)
01-25 09:30:03.730: ERROR/AndroidRuntime(11748):     at android.app.ContextImpl.unregisterReceiver(ContextImpl.java:814)
01-25 09:30:03.730: ERROR/AndroidRuntime(11748):     at android.content.ContextWrapper.unregisterReceiver(ContextWrapper.java:331)
01-25 09:30:03.730: ERROR/AndroidRuntime(11748):     at com.myservice.Service.onStart(Service.java:291)
01-25 09:30:03.730: ERROR/AndroidRuntime(11748):     at android.app.Service.onStartCommand(Service.java:420)
01-25 09:30:03.730: ERROR/AndroidRuntime(11748):     at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3053)
01-25 09:30:03.730: ERROR/AndroidRuntime(11748):     ... 10 more

你能帮帮我吗?

最佳答案

修改你的代码如下

public void onStart() {
    if(something....) {
        IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
        filter.addAction(Intent.ACTION_SCREEN_OFF);
        screenReceiver = new ScreenReceiver();
        registerReceiver(screenReceiver, filter);
    } else {
        if(screenReceiver != null) {
            unregisterReceiver(screenReceiver);
            screenReceiver = null;
        }
    }
}

调用 unregisterReceiver() 不会将 screenReceiver 设置为 null,当控件到达该 block 时,您的接收器可能并不总是已注册。 例如考虑按顺序执行,

  1. if(something...) 为真,因此 screenReceiver 被实例化并注册。
  2. if(something...) 这次是 false,所以 screenReceiver 未注册。
  3. if(something...) 再次为 false,此处,screenReceiver 在步骤 1 中实例化,因此它不为空,但在步骤 2 中未注册,因此出现异常“Receiver not registered: com .myreceiver.ScreenReceiver@46079370".

screenReceiver设置为null后,依次考虑以上3个步骤。它将正确执行。

关于android - 注销 BroadcastReceiver,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4791379/

相关文章:

android - 主线程外的前台服务?

android - 在 Play 商店中启动应用程序后, fragment 工具栏后退按钮未显示

android - 具有多个过滤器或多个广播接收器的广播接收器?

键盘可见后,Android WindowManager 窗口不会重新定位

android - 更新小部件 onClick,启动服务似乎不起作用

android - AlarmManager 无法从广播接收器工作

android - Google Drive SDK - 在上传完成时获取资源 ID

android - OpenCV 检测手和比较图像

android - 如何在 BroadcastReceiver.onReceive 中设置 RecyclerView.ViewHolder 的颜色?

java - Android,BroadCastReceiver 中的 onReceive 被多次调用