java - onPause中的unregisterReceiver(receiver)导致接收者不注册

标签 java android android-intent broadcastreceiver

各位超人大家好。我的 BroadcastReciever 有问题 - 我知道存在大量问题和答案,因为过去 2 天我一直在尝试每个问题和答案,所以如果您确实想将其标记为重复,请检查代码是否正确与我已经写过的内容不匹配(因为我几乎肯定是从 SO 答案中复制了它)。

我们开始吧:

我想检测在我的基本 Activity 中打开或关闭的锁定屏幕 - 我的所有其他 Activity 都从该 Activity 延伸

public abstract class BaseActivity extends AppCompatActivity{////

这里我有成员变量

BroadcastReceiver receiver;
IntentFilter filter;

我这样分配:

receiver = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    if (intent.getAction() != null && intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
                        //do some code
                    } else {
                       //do something else
                    }
                }
            };


filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);

如果我把它放在 onCreate()onResume() 中,它就会按预期工作,并且我可以成功调用 registerReceiver(receiver, filter) code> 在创建或恢复中都可以正常工作。

我不希望它在应用程序暂停时处于 Activity 状态,因此所有各种​​答案和教程都建议我在 onPause 中取消注册它

     @Override
        protected void onPause() {
//I have commented both out to demonstrate that I have tried both before and after the calling the superclass
      //    this.unregisterReceiver(receiver);
            super.onPause();
    //      unregisterReceiver(receiver);

        }

当我包含此取消注册调用时,它会阻止注册发生。我尝试过在 onCreate、onResume 和两者中注册。我可以在整个 Activity 中移动组合,但是一旦我引入取消注册,它就根本不起作用 - 甚至没有错误或崩溃(否则我会在此处包含堆栈跟踪)。

我能够实现的最终目标是:

receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
  if (intent.getAction() != null && intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
  //do some code 
  unregisterReceiver(receiver);

通过将取消注册放入 onRecieve 中,我可以取消注册接收器并正确重新注册它,除非如果我的应用程序堆栈中有多个 Activity ,我会收到内存泄漏错误和跟踪请求,而不是如果我忘记添加取消注册调用,那就居高临下。

那么有谁知道为什么向 onPause() 添加取消注册调用会导致接收器完全取消?

最佳答案

正如我所想,您遇到此问题是因为系统在 onStop() 方法之后发送 ACTION_SCREEN_OFF,因此您无法处理它,因为您已经取消注册了它。不知道为什么你不能处理 SCREEN_ON 事件,因为当我测试这个时,我看到系统在 onResume() 之后发送它。这是我的日志中的内容:

D/TEST: onPause:
D/TEST: onStop:
D/TEST: onReceive: action = android.intent.action.SCREEN_OFF
D/TEST: onStart:
D/TEST: onResume:
D/TEST: onReceive: action = android.intent.action.SCREEN_ON

我认为,它是在 onResume 调用之前发送的,但在调用之后交付。

所以,我的解决方案是在 onCreate(@Nullable Bundle savingInstanceState) 中注册接收器并在 onDestroy() 中取消注册,这就是我获取此日志的方式。

更新1:这就是我在onCreate(@Nullable Bundle savingInstanceState)

中注册接收器的方式
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(new TestReceiver(), filter);

更新 2:我错过了,如果您的 Activity 暂停,您不需要接收事件。如果您不想在 Activity 暂停时执行某些代码,我可以建议您创建简单的枚举:

枚举 ActivityState { 开始、恢复、暂停、停止 }

和私有(private)变量ActivityState currentState。然后在生命周期方法中将适当的状态分配给 currentState。然后在您的接收器 onReceive() 方法中,您可以检查当前状态并根据状态执行您想要的操作。 应用程序处于 Activity 状态时记录:

D/TEST: onReceive: action = android.intent.action.SCREEN_OFF, current Activity state = STOPED
D/TEST: onReceive: action = android.intent.action.SCREEN_ON, current Activity state = RESUMED

并在应用程序未处于 Activity 状态时记录:

D/TEST: onReceive: action = android.intent.action.SCREEN_OFF, current Activity state = STOPED
D/TEST: onReceive: action = android.intent.action.SCREEN_ON, current Activity state = STOPED

希望对您有帮助!

关于java - onPause中的unregisterReceiver(receiver)导致接收者不注册,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55710739/

相关文章:

android - 强制特定设备的用户在 Google Play 商店中安装特定版本

java - 我得到一个 FileNotFoundException 但文件在那里

java - RecyclerView 中的 OnClickListener 具有图像、文本

Android Intent.FLAG_ACTIVITY_SINGLE_TOP 和 Intent.FLAG_ACTIVITY_CLEAR_TOP

java - JFrame 仅在调整大小后显示内容 (Xuggler)

Android Tab下划线颜色不变

iphone - iPhone、Android 或 WP7 电话设备可以在没有服务计划的情况下使用吗?

java - spring-mvc 何时使用@CookieValue

java : read/write neo4j server database

java - 插件与 dropins 和功能之间有什么区别?