2013-08-26 23 views
5

我建立一個庫,它具有以下結構:如何避免廣播接收器泄漏

MySDK{ 
    public static void init(Context context){ 
     registerReceivers(); // Register connectivity BroadcastReceiver here 
    } 

    public static void performAction(){}; 
} 

的預期用途是:我的庫調用的init()第一活動的用戶他們創造。問題是我沒有取消註冊BroadcastReceiver,它在應用程序關閉時泄漏。我可以創建一個名爲deinit()的方法,並要求lib的用戶在離開活動時調用它,但有沒有更可靠的方式來釋放資源?

爲什麼我需要接收器嗎?

如果沒有互聯網連接並且performAction()無法發送數據,我註冊接收器來檢測連接狀態的變化。

+0

只有在第一項活動中需要廣播接收機還是需要更長時間? – Simon

+0

@Simon查看更新。我會一直需要接收器。 –

+0

創建註冊此接收器的服務。 –

回答

3

如果聲明清單中的android廣播接收器會照顧的登記處理。

註冊您的接收器應用標籤內這樣

<receiver android:name="class name with package"> 
     <intent-filter> 
      <action android:name=" corresponding broadcast name" /> 
     </intent-filter> 
</receiver> 
+1

爲了避免註冊多個接收者的問題,您可以直接獲得。它也不需要爲了接收通知而手動啓動應用程序。 –

0

一旦onReceive方法結束(在它的結尾),您可以取消註冊接收方。

但我不知道這是否適合你,這取決於你的接收器做什麼。

註冊SMSsent /交付接收器時,它的工作對我來說..

2

爲什麼不僅註冊了接收器的performAction如果()需要推遲行動?如果實際上有些事情需要完成,這將限制接收機只能在適當的位置。一旦接收器成功清除其操作隊列,它可以取消註冊接收器本身。

0

你有沒有想過擴大android.app.Application和實現這些方法:

void onCreate() 

void onLowMemory() 

您可以註冊需要裏面的onCreate所有BroadcastReceivers和註銷「時間內onLowMemory。

要檢索此類的引用,您可以調用context.getApplicationContext()並將其轉換爲您的Application子類。

最後,爲了讓您的應用程序使用此解決方案,你必須把標籤內的這些信息您的AndroidManifest.xml中那樣:

<application 
    android:allowBackup="true" 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" 
    android:name="[fully qualified name of your Application subclass]" > 
... 
</application> 
0

如果您需要在所有的活動,就應該建立哪些寄存器接收器,here你可以看到如何創建一個服務的服務接收器。

要取消註冊接收器,您可以檢測到用戶何時完成了解當前位於前臺的包名的應用程序。當您不再需要接收器時,您將註銷接收器,當用戶退出應用程序時它不會泄漏,因爲它現在已創建並連接到服務,而不是應用程序或活動。

public String getForegroundApp() throws NameNotFoundException{ 

     RunningTaskInfo info = null; 
     ActivityManager am; 
     am = (ActivityManager)mContext.getSystemService(ACTIVITY_SERVICE); 
     List<RunningTaskInfo> l = am.getRunningTasks(1000); 
     System.out.println(l); 
     Iterator <RunningTaskInfo> i = l.iterator(); 


     String packName = new String(); 
     String appName = new String(); 
     ApplicationInfo appInfo = new ApplicationInfo(); 

     while(i.hasNext()){ 
      info = i.next(); 
      packName = info.topActivity.getPackageName(); 
      if(!packName.equals("com.htc.launcher") && !packName.equals("com.android.launcher")){ //this could be what is causing the problem. not sure. 
       packName = info.topActivity.getPackageName(); 
       break; 
      } 
      info = i.next(); 
      packName= info.topActivity.getPackageName(); 
      break;   
      } 
     return packName; 
     } 

無論如何,我認爲你應該創造這樣一個stop()方法,讓用戶調用它來完成你想要的一切,當他們知道正在退出應用程序和庫是沒有不再需要。

+0

服務始終由系統保持運行。對於這種情況來說,這是一個巨大的資源浪費,服務無關,只是成爲接收方的佔位符。 –