为什么我的活动泄漏?(Why does my Activity leak?)

2019-09-19 01:02发布

我有一个具有IntentFilter的和广播接收器的活动,我将它们注册在我onCreate()

IntentFilter filter = new IntentFilter(ACTION_RCV_MESSAGE);
filter.addCategory(Intent.CATEGORY_DEFAULT);
receiver = new MessageReceiver();
registerReceiver(receiver, filter);

但在结束我的应用程序,logcat的说:

一月七日至3日:38:19.567:ERROR / ActivityThread(304):android.app.IntentReceiverLeaked:活动com.intentservicetest5.IntentServiceTest5Activity已泄漏,最初这里注册IntentReceiver com.intentservicetest5.IntentServiceTest5Activity$MessageReceiver@44efe8a8。 你缺少unregisterReceiver()的调用?

但我有

public void onDestroy(Bundle savedInstanceState){
    unregisterReceiver(receiver);
}

为什么我的活动仍然漏水的时候我叫unregisterReceiver()

Answer 1:

每活动的生命周期 ,应用程序是killable任何时间之后onPause()在大多数设备上,和之后的任何时间(具有小于3.0的Android / API级12的任何装置) onStop()的任何设备上。 这意味着onDestroy()不能保证被调用。 在一个活动的最佳位置注册和注销用于广播,然后,是onResume()onPause()分别为:

@Override
protected void onResume() {
    super.onResume();

    IntentFilter filter = new IntentFilter(ACTION_RCV_MESSAGE);
    filter.addCategory(Intent.CATEGORY_DEFAULT);
    receiver = new MessageReceiver();
    registerReceiver(receiver, filter);
}

@Override
protected void onPause() {
    super.onPause();

    unregisterReceiver(receiver);
}

注意,@VipalShah指出的那样,你用错了签名onDestroy() 这就是为什么unregisterReceiver()没有被调用。 使用@Override将帮助您捕捉这类问题。

还要注意的是之间的对称onPause()onResume()是故意的。 如果你看一下链接到上面的活动周期的文章,你会看到onResume()的初始启动时被调用时,从暂停恢复不只是当。 所以,你只需要为广播这里注册,而不是onCreate()

最后,请注意,我用你的代码的简单性。 在现实中,你可能会想设置您的IntentFilter并在的messageReceiver onCreate()然后只需调用registerReceiver()onResume()

更新:一个更重要的注释。 按照实施生命周期回调 :

您实现这些生命周期方法必须做任何工作之前,总是调用父类的实现。

这里的许多人都表示调用super.onWhatever()在方法的结束而不是开始。



Answer 2:

的onDestroy并不总是保证被调用时,应用程序退出。 你应该尝试注销它的onStop在onPause。

此外,请确保你打电话给你活动的父类方法在覆盖的方法:

@Override
public void onPause() {
    unregisterReceiver(receiver);
    super.onPause();
}


Answer 3:

尝试使用这个的onDestroy()

@Override
protected void onDestroy() {

    unregisterReceiver(receiver);

    super.onDestroy();
}


Answer 4:

    @Override
        protected void onPause() {
            super.onPause();
            unregisterReceiver(receiver);
        }   

尝试在onPause()



文章来源: Why does my Activity leak?