2012-07-02 71 views
4

我在我的應用中實現了GCM,並且我使用GSMRegistrar作爲建議here。不,我得到一個錯誤的logcatGoogle Cloud Messaging中的泄漏IntentReceiver

7-02 23:35:15.830: E/ActivityThread(10442): Activity com.abc.xyz.mnp has leaked IntentReceiver [email protected] that was originally registered here. Are you missing a call to unregisterReceiver()? 

我可以從這個理解是什麼,看着爲GSMRegistrar代碼是我需要調用GSMRegistrar.onDestroy(this)但我不明白的地方我應該怎麼稱呼呢?調用onDestroy()活動mnp導致它停止重試GSM Registartion

回答

12

您可以使用應用程序上下文,而不是活動場景。這樣退避機制不受活動生命週期的限制。

+0

謝謝。它有助於。 例如: 它是這樣的:GCMIntentService.register(getApplicationContext()); 而不是像這樣:GCMIntentService.register(RegisterActivity.this); –

8

它應該在您啓動GCM註冊的活動的onDestory()方法內調用。

請記住,即使在其上啓動了其他活動,活動也不會被破壞。所以你的註冊仍然可以在後臺重試。如果註冊活動被破壞,那麼您的GCMBroadcastReceiver類將不會在那裏處理響應。

更新:在GCM庫的源代碼更仔細尋找後,這裏是我觀察到:

  1. 的GCM庫使用活動上下文註冊一個接收器,重試登記的目的,如果它失敗時,它將使用退避機制重試。
  2. 您應該在您的活動的onDestroy()方法上調用GCMRegistrar.onDestroy(),這是在活動銷燬之前取消註冊接收方的一種很好的Android實踐。
  3. 由於#2,這意味着如果調用GCMRegistrar.register的活動被銷燬,您的應用程序將不會嘗試重新註冊。用戶必須返回到此活動以便註冊過程再次啓動。
  4. 如果您不想要#3行爲,您可能必須實施自己的GCM註冊和重試機制。例如,如果重試機制是在單獨的後臺線程中完成的,那麼即使該活動被銷燬,只要應用程序正在運行,它也可以繼續嘗試。

我認爲#3是可以接受的,因爲GCM服務器很少會拒絕註冊'SERVICE_NOT_AVAILABLE'錯誤。只要你的用戶運行你的應用幾次,他們的設備遲早會成功註冊。

+0

嗨,謝謝你的回答。我試圖理解你的觀點*如果註冊活動被破壞,那麼你的GCMBroadcastReceiver類將不會在那裏處理響應。*你爲什麼這麼說? –

+1

當您調用GCMRegistrar.register(this,xxxx); GCM庫正在使用您的活動的上下文來處理響應。如果您的活動被操作系統銷燬(可能是在內存不足的情況下),那麼該上下文不再有效,所以如果從GCM庫收到響應,應用程序可能會引用已銷燬的上下文,從而導致不可預知的結果。因此,當活動被銷燬時,調用GCMRegistrar.onDestory()會更安全。 – azgolfer

+0

+1您的評論,讓我更多的工作。爲什麼不使用應用程序上下文而不是活動上下文 –

2

你必須摧毀GCMRegistrar在activty類的你的onDestroy方法

 unregisterReceiver(receiver); 
     GCMRegistrar.onDestroy(this);