2010-08-26 74 views
14

我不明白为什么我点击后退按钮时得到这个异常。我有IntentReceiver在onCreate方法中注册,它应该在onPause方法中注销。在onPause方法内我的Log.w()调用使我相信正在调用unregisterReceiver()方法,但我仍然得到这个异常。Android:泄露的IntentReceiver异常正在抛出,即使我打电话unregisterReceiver

有什么想法?

private PlayerReceiver playerReceiver; 

public void onCreate(Bundle savedInstanceState) { 
... 
    IntentFilter playerFilter;  
    playerReceiver = new PlayerReceiver(); 
    playerFilter = new IntentFilter(PlayerService.BUFFERING_FAILURE); 
    playerFilter.addAction(PlayerService.BUFFERING_SUCCESS); 
    registerReceiver(playerReceiver, playerFilter); 
... 
} 

protected void onPause() { 
... 
    if (playerReceiver != null){ 
     unregisterReceiver(playerReceiver); 
     Log.w(TAG, "playerReceiver has been unregistered"); 
     playerReceiver = null; 
    } 
... 
} 

public class PlayerReceiver extends BroadcastReceiver { 

    public void onReceive(Context context, Intent intent) { 
     if (intent.getAction().equals(PlayerService.BUFFERING_FAILURE)){ 
      setListenButton(false); 
     } 
     closePlayDialog(); 
    } 
} 

logcat的输出

08-26 11:44:28.646: WARN/WWOZMain(1058): playerReceiver has been unregistered  
08-26 11:44:29.476: ERROR/ActivityThread(1058): Activity org.wwoz.WWOZMain has leaked IntentReceiver [email protected] that was originally registered here. Are you missing a call to unregisterReceiver()?  
08-26 11:44:29.476: ERROR/ActivityThread(1058): android.app.IntentReceiverLeaked: Activity org.wwoz.WWOZMain has leaked IntentReceiver [email protected] that was original 

LY这里注册。你是否错过了对unregisterReceiver()的调用?

+4

通常你应该在'onResume'中注册并在'onPause'(或'onStart'和'onStop')注销。因此,在活动恢复时,您可能会多次取消注册,而无需重新注册。这看起来与您遇到的问题相反,但我猜它可能仍会触发相同的日志警告? – 2010-08-26 22:35:28

+0

啊!谢谢克里斯托弗。我甚至没有注意到我在'onCreate'和'onResume'中注册接收器的事实。相反,我注册了两次,只注销一次。卫生署! – 2010-08-27 00:34:47

回答

20

这是一个Android活动生命周期问题。我在主要活动中看到它,然后使用后退按钮在设备上进行测试,然后返回到启动画面。

onPause()方法中。

注销您在onCreate()

创造了onRestart()BroadcastReceiver重新注册一个全新的广播接收器。

在活动类中,您需要将广播接收器记录为实例数据成员。

第二

我想这也与Android功能增强的问题。

有时开发人员需要一个广播接收器才能使活动活跃起来。例如,了解某些屏幕状态何时可用。考虑有很多状态的工作流模型的对话环境。

第三

您可以注册和注销广播接收机同一个活动,但像在Activity类isRegistered(BroadcastReceiver)一个简单的通话可能是非常有用的。

如果您需要接收器超出活动范围,那么我不会回答,只能通过在onDestroy()呼叫中添加unregister(X)来消除警告。 YMMV ;-)

8

我有完全相同的问题。 原因是我无意中注册了两次相同的BroadcastReceiver。

3

我的情况与Mullins类似,我在一个类及其子类中注册了一个接收器。

对于像我这样的新手,只需在receiver处切换一个断点,然后调试您的应用程序。如果接收方是类似[email protected]的东西,而logcat中的错误日志与它不同(如[email protected]),而“@”后面的字符不同,那么您肯定会注册两次(或更多)。

(上面喜欢根据Mullins的回答评论,实际上,我在这里发布它,因为我现在无法发表评论。)

相关问题