2011-07-24 102 views
4

onReceive方法中的線程是否有資格進行垃圾回收,然後才能完成?onReceive異步操作和垃圾回收

@Override 
public void onReceive(final Context context, Intent intent) { 
    final int alarmId = intent.getExtras().getInt(EXTRA_ALARM_ID); 
    Log.i(TAG, "/onReceive with an alarmVo.id of " + alarmId); 

    // RUN MY THREAD 
    new Thread(new Runnable() { 
     @Override 
     public void run() { 
      AlarmUtil.setNextAlarm(context, alarmId); 
     } 
    }).start(); 
} 

從我從這裏瞭解: http://developer.android.com/reference/android/content/BroadcastReceiver.html它是,但我不是很肯定。

「任何需要異步操作不可用,因爲你需要從處理異步操作的功能恢復,但在這一點上的BroadcastReceiver不再有效,因此該系統是免費殺其過程在異步操作完成之前「。

如果它被垃圾收集,那麼我該如何解決這個問題?我應該怎麼做?

回答

6

編號任何已經通過start()方法啓動的尚未完成的Thread對象充當垃圾收集根目錄...既不強制引用它也沒有資格進行垃圾收集直到其運行()方法完成。

又見這些問題的答案:

編輯: 現在你已經增加了額外的背景下你的問題的東西更清楚一點。問題是這種情況與垃圾收集完全不同。對於靜態發佈的BroadcastReceiver(在具有<receiver>標籤的應用程序清單中定義),Android可在onReceive(Context, Intent)返回後自由終止其進程。您的異步操作不會因GC而停止,它會因Android停止託管它的進程而停止。

至於你的方法,這一切都取決於你想要完成的。如果您想在您的BroadcastReceiver中執行的代碼可以同步運行,那麼這將是最簡單的方法。我假設這是不可能的。在這種情況下,該文檔的this portion似乎適用(重點煤礦):

一旦你的onReceive()返回時,廣播接收器不再是活動的,它的宿主進程只是像任何其他應用程序組件一樣重要它正在運行。這一點尤其重要,因爲如果該進程僅託管BroadcastReceiver(用戶從未或最近未與之交互過的應用程序的常見情況),那麼在從onReceive()返回時,系統將認爲其進程是空的並積極地殺死它使資源可用於其他更重要的流程。

這意味着對於長時間運行的操作,您經常會使用服務與BroadcastReceiver一起使您的操作在整個操作過程中始終處於活動狀態

因此,要麼同步運行您的接收器代碼,要麼使用服務來保持異步操作的活動時間足夠長以完成。(當然,這隻有在你將接收器靜態註冊到一個不活動的應用中時才適用,如果你是從一些其他活動組件(比如一個Activity)動態地註冊它,那麼這個組件可以管理你的異步有關更多信息,請參閱this answer。)

+0

您可以進一步解釋此處的含義:「任何需要異步操作的地方都不可用,因爲您需要從函數返回以處理異步操作,但此時BroadcastReceiver不再處於活動狀態,因此係統可以在異步操作完成之前自由地終止它的進程。「 – user123321

+0

我編輯了我的答案,現在已添加更多上下文。希望能幫助到你。 –

+0

是的。謝謝你,先生!你是一個紳士和學者。 – user123321