4

我已经在我的应用程序中实现了 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()?

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

4

3 回答 3

12

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

于 2012-07-13T15:08:36.737 回答
8

它应该在您开始 GCM 注册的活动的 onDestory() 方法中调用。

请记住,一个活动可能不会被销毁,即使在它之上启动了另一个活动。所以您的注册仍然可以在后台重试。如果注册活动被破坏,那么您的 GCMBroadcastReceiver 类将无法处理响应。

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

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

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

于 2012-07-02T20:46:41.077 回答
2

您必须在 activty 类的 onDestroy 方法中销毁 GCMRegistrar

        unregisterReceiver(receiver);
        GCMRegistrar.onDestroy(this);
于 2012-07-03T10:06:35.053 回答