68
01-16 16:52:42.211: E/ActivityThread(2529): Activity com.Civilcourage.CivilcurageSplash has leaked IntentReceiver com.google.android.gcm.GCMBroadcastReceiver@405282e0 that was originally registered here. 

Are you missing a call to unregisterReceiver()?

上述错误的原因是什么?如何避免?

4

6 回答 6

61

不要依赖 onStop()因为

请注意,在调用 onPause() 方法后系统没有足够内存来保持活动进程运行的低内存情况下,可能永远不会调用此方法

更多关于 Activity 生命周期的信息

在 onPause() 中取消注册您的接收器:

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

    unregisterReceiver(yourReceiver);
}
于 2014-01-07T21:41:34.863 回答
48

您需要在活动停止时注销您的接收器:

@Override
protected void onStop()
{
    unregisterReceiver(yourReceiver);
    super.onStop();
}
于 2013-01-16T11:43:14.573 回答
8

您可以unregister在收到后立即broadcastreceiver

 @Override
 public void onReceive(Context context, Intent intent) {
     getActivity().unregisterReceiver(this);
 }
于 2013-10-28T20:16:12.070 回答
4

只是为了补充上面的答案,如果您在 onCreate 中注册了一个接收器,它应该在 onDestroy 中取消注册。如果你在 onResume 上注册了一个接收者,你应该在 onPause 中取消注册它。

请注意在哪里注册和取消注册接收器,例如,如果您使用活动的上下文在 onCreate(Bundle) 中注册接收器,则应在 onDestroy() 中取消注册它以防止将接收器泄漏到活动上下文之外。如果你在 onResume() 中注册了一个接收器,你应该在 onPause() 中取消注册它以防止它被多次注册(如果你不想在暂停时接收广播,这可以减少不必要的系统开销)。不要在 onSaveInstanceState(Bundle) 中取消注册,因为如果用户移回历史堆栈,则不会调用它。

资源

于 2018-01-22T01:34:43.000 回答
2

在取消注册之前,请确保接收者已注册。为此,声明一个布尔值

private boolean isReceiverRegistered = false;

然后在调用 registerReceiver() 方法之后,将标志设置isReceiverRegistered为 true,如下面的代码片段所示

registerReceiver(broadcastReceiver, new IntentFilter("anyString"));
    isReceiverRegistered = true;

那么,在onPause()

 @Override
protected void onPause() {
    super.onPause();
    if(isReceiverRegistered){
        unregisterReceiver(broadcastReceiver);
        isReceiverRegistered = false;// set it back to false.
    }
}
于 2018-12-19T08:12:00.790 回答
2

在 onStop() 上取消注册您的接收器是有效的答案。不要在 onPause() 方法上调用它。

@Override
protected void onStop()
{
    unregisterReceiver(yourReceiverName);
    super.onStop();
}
于 2016-07-28T01:34:57.087 回答