2

我有一个具有 IntentFilter 和 BroadcastReceiver 的 Activity,我将它们注册到我的onCreate().

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

但是在结束我的应用程序时,Logcat 说:

07-03 01:38:19.567: ERROR/ActivityThread(304): android.app.IntentReceiverLeaked: Activity com.intentservicetest5.IntentServiceTest5Activity 泄露了最初在此处注册的 IntentReceiver com.intentservicetest5.IntentServiceTest5Activity$MessageReceiver@44efe8a8。您是否错过了对 unregisterReceiver() 的调用?

但我确实有

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

为什么我打电话时我的活动仍然泄漏unregisterReceiver()

4

4 回答 4

5

根据Activity Lifecycle,您的应用程序onPause()在大多数设备(低于 Android 3.0 / API 级别 12 的任何设备)之后的任何时间都可以被终止,并且onStop()在任何设备上之后的任何时间都可以终止。这意味着onDestroy()不能保证被调用。那么,在 Activity 中注册和注销广播的最佳位置分别是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()有意的。如果您查看上面链接的 Activity 生命周期文章,您会发现它onResume()在初始启动期间被调用,而不仅仅是在从暂停中恢复时。所以你只需要在这里注册广播,而不是在onCreate().

最后,请注意,为了简单起见,我使用了您的代码。实际上,您可能希望在 in 中设置 IntentFilter 和 MessageReceiver onCreate(),然后只需调用registerReceiver()in onResume()

更新:一个更重要的注意事项。根据实现生命周期回调

这些生命周期方法的实现必须始终在执行任何工作之前调用超类实现。

这里的许多人都super.onWhatever()在方法的末尾而不是在开头显示调用。

于 2012-07-03T04:51:00.747 回答
1

onDestroy并不总是保证在应用程序退出时被调用。您应该尝试取消注册onStoponPause

此外,请确保在覆盖的方法中调用 Activity 的超类方法:

@Override
public void onPause() {
    unregisterReceiver(receiver);
    super.onPause();
}
于 2012-07-03T04:29:42.857 回答
0
    @Override
        protected void onPause() {
            super.onPause();
            unregisterReceiver(receiver);
        }   

试试看onPause()

于 2012-07-03T04:29:35.257 回答
0

尝试使用这个 onDestroy()

@Override
protected void onDestroy() {

    unregisterReceiver(receiver);

    super.onDestroy();
}
于 2012-07-03T04:43:12.950 回答