问题
I have implemented GCM in my app and I am using GSMRegistrar as suggested here. No I am getting an error in logcat
7-02 23:35:15.830: E/ActivityThread(10442): Activity com.abc.xyz.mnp has leaked IntentReceiver com.google.android.gcm.GCMBroadcastReceiver@44f8fb68 that was originally registered here. Are you missing a call to unregisterReceiver()?
What I can understand from this and looking at the code for GSMRegistrar
is I need to to call GSMRegistrar.onDestroy(this)
but I could not understand where should I call this? Calling in onDestroy()
of activity mnp
causes it to stop retrying for GSM Registartion
回答1:
You may use the application context, instead of the activity context. That way the backoff mechanism is not restricted by the activity life cycle.
回答2:
It should be called inside onDestory() method of the activity that you started the GCM registration.
Keep in mind an activity may not be destroyed, even though another activity is launched on top of it. So your registration could still be retried in the background. If the registration activity is destroyed, then your GCMBroadcastReceiver class won't be there to handle the response anyway.
Update: After looking at the GCM library source code more carefully, here's what I've observed:
- The GCM library uses the activity context to register a receiver, for the purpose of retrying registration if it fails, it will use a backoff mechanism to retry.
- You should call GCMRegistrar.onDestroy() on your activity's onDestroy() method, it's a good Android practice to unregister a receiver before activity is destroyed.
- Because of #2, it means that your app won't attempt to re-register, if the activity that calls GCMRegistrar.register is destroyed. The user has to go back to this activity for the registration process to kick off again.
- If you don't want behavior #3, you may have to implement your own GCM registration and retry mechanism. For example, if the retry mechanism is done in a separate background thread, then it could keep on trying even though the activity is destroyed, as long as the application is running.
I think #3 is acceptable, as it's very rare that the GCM server will reject the registration with 'SERVICE_NOT_AVAILABLE' error. And as long as your user runs your app a few times, sooner or later their device will have successful registration.
回答3:
you have to destroy GCMRegistrar in your onDestroy method of activty class
unregisterReceiver(receiver);
GCMRegistrar.onDestroy(this);
来源:https://stackoverflow.com/questions/11299312/leaked-intentreceiver-in-google-cloud-messaging