Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: Leaked IntentReceiver exception is being thrown even though I call unregisterReceiver

I don't understand why I'm getting this exception when hitting the back button. I have the IntentReceiver registered in the onCreate method and it is supposed to be unregistered in the onPause method. My Log.w() call inside of the onPause method leads me to believe that the unregisterReceiver() method is being called, but I am getting this exception still.

Any thoughts?

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 Output

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 org.wwoz.WWOZMain$PlayerReceiver@43e4dd60 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 org.wwoz.WWOZMain$PlayerReceiver@43e4dd60 that was original

ly registered here. Are you missing a call to unregisterReceiver()?

like image 921
Doug Miller Avatar asked Aug 26 '10 17:08

Doug Miller


2 Answers

This is a Android activity life cycle issue. I am seeing it in a main activity and then testing on device with the back button that goes back to a splash screen.

In the onPause() method.

Unregister the BroadcastReceiver that you created in the onCreate()

In the onRestart() re-register a brand new Broadcast Receiver.

In the activity class you need to keep a record of the Broadcast Receiver as instance data member.

SECOND

I think this also a feature enhancement issue with Android.

Sometimes developer need a broadcast receiver to outlive the activity. For example to understand when certain screen states are available or not. Think about a conversation context of work flow model, which has many states.

THIRD

You can register and unregister broadcast receivers with an activity, but a simple call like isRegistered(BroadcastReceiver) in the Activity class might be very useful.

If you need receivers to live beyond the activity, then I do not the answer, except to silence the warning, by adding unregister(X) in the onDestroy() call. YMMV ;-)

like image 116
peter_pilgrim Avatar answered Oct 09 '22 11:10

peter_pilgrim


I had the exact same problem. The cause was that I had inadvertently registered the same BroadcastReceiver twice.

like image 43
Mullins Avatar answered Oct 09 '22 11:10

Mullins