Activity已泄露最初在此处注册的IntentReceiver。你是否错过了对unregisterReceiver()的调用?

时间:2013-01-16 11:39:07

标签: android

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()?

上述错误的原因是什么? 怎么可以避免?

6 个答案:

答案 0 :(得分:50)

不要依赖onStop()because

  

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

有关活动生命周期的更多信息here

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

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

    unregisterReceiver(yourReceiver);
}

答案 1 :(得分:44)

您需要在停止活动时取消注册接收器:

@Override
protected void onStop()
{
    unregisterReceiver(yourReceiver);
    super.onStop();
}

答案 2 :(得分:5)

收到unregister

后,您可以broadcastreceiver
 @Override
 public void onReceive(Context context, Intent intent) {
     getActivity().unregisterReceiver(this);
 }

答案 3 :(得分:4)

只是为了添加上面的答案,如果你在onCreate上注册接收者,它应该在onDestroy中注销。如果你在onResume上注册一个接收者,你应该在onPause中注销它。

  

请注意注册和取消注册接收器的位置,例如,如果使用活动的上下文在onCreate(Bundle)中注册接收器,则应在onDestroy()中取消注册,以防止接收器泄漏到活动上下文之外。如果在onResume()中注册接收器,则应在onPause()中注销它以防止多次注册(如果您不希望在暂停时接收广播,这可以减少不必要的系统开销)。不要在onSaveInstanceState(Bundle)中取消注册,因为如果用户在历史堆栈中向后移动,则不会调用此方法。

Source

答案 4 :(得分:2)

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

@Override
protected void onStop()
{
    unregisterReceiver(yourReceiverName);
    super.onStop();
}

答案 5 :(得分:1)

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

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.
    }
}
相关问题