我有一个具有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()
时,我的活动仍在泄露?
答案 0 :(得分:5)
根据Activity Lifecycle,您的应用在onPause()
之后的任何时间都可以在大多数设备(任何低于Android 3.0 / 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()
。
最后,请注意我使用您的代码是为了简单。实际上,您可能希望在onCreate()
中设置IntentFilter和MessageReceiver,然后只需在registerReceiver()
中调用onResume()
。
更新:还有一个重要提示。根据{{3}}:
在执行任何工作之前,您对这些生命周期方法的实现必须始终调用超类实现。
这里有很多人在方法结束时而不是在开头时显示对super.onWhatever()
的调用。
答案 1 :(得分:1)
onDestroy 被调用。您应该尝试取消注册 onStop 或 onPause 。
另外,请确保在覆盖的方法中调用Activity的超类方法:
@Override
public void onPause() {
unregisterReceiver(receiver);
super.onPause();
}
答案 2 :(得分:0)
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(receiver);
}
在onPause()
答案 3 :(得分:0)
尝试使用此onDestroy()
@Override
protected void onDestroy() {
unregisterReceiver(receiver);
super.onDestroy();
}