Google Cloud Messaging中泄漏的IntentReceiver

Gau*_*wal 4 android android-c2dm google-cloud-messaging

我在我的应用程序中实现了GCM,并且我正在使用GSMRegistrar,如此处所示.不,我在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()?
Run Code Online (Sandbox Code Playgroud)

我能从中理解并查看代码GSMRegistrar是我需要打电话GSMRegistrar.onDestroy(this)但我无法理解我应该在哪里调用它?调用onDestroy()活动mnp会导致它停止重试GSM Registartion

ran*_*ser 12

您可以使用应用程序上下文,而不是活动上下文.这样,退避机制不受活动生命周期的限制.


azg*_*fer 8

它应该在您启动GCM注册的活动的onDestory()方法内部调用.

请记住,即使在其上启动了另一项活动,也不会销毁活动.因此,您的注册仍可在后台重试.如果注册活动被销毁,那么GCMBroadcastReceiver类将不会在那里处理响应.

更新:更仔细地查看GCM库源代码之后,这是我观察到的:

  1. GCM库使用活动上下文来注册接收器,如果失败则重试注册,它将使用退避机制重试.
  2. 你应该在你的活动的onDestroy()方法上调用GCMRegistrar.onDestroy(),在活动被销毁之前取消注册接收器是一个很好的Android实践.
  3. 由于#2,这意味着如果调用GCMRegistrar.register的活动被销毁,您的应用将不会尝试重新注册.用户必须返回此活动才能重新启动注册过程.
  4. 如果您不想要行为#3,则可能必须实现自己的GCM注册和重试机制.例如,如果重试机制是在单独的后台线程中完成的,那么只要应用程序正在运行,即使活动被销毁,它也可以继续尝试.

我认为#3是可以接受的,因为很少有GCM服务器拒绝注册'SERVICE_NOT_AVAILABLE'错误.只要您的用户运行您的应用几次,他们的设备迟早会成功注册.