2011-06-01 43 views
15

在我的Android應用中,主Activity有時會啓動一個Thread來從服務器加載數據。此線程修改應用程序的數據庫並編輯一些重要的文件。 AFAIK,看來這個線程繼續執行。如果Android進入低內存環境並決定終止整個應用程序,該線程會發生什麼?這個線程是否會過早死亡?如果是這樣,有什麼辦法可以看到線程正在被殺死,並對此做些什麼?在創建它的Activity被銷燬後,Android線程會發生什麼?

我在問,因爲這個線程修改數據庫中的重要數據,如果它突然死亡,應用程序可能會停止正常運行。

回答

13

據我所知,它會出現,這個線程繼續執行。

這是事實,但您無法保證線程將保持活動狀態的時間。

如果Android進入低內存狀態並決定終止整個應用程序,該線程會發生什麼?

在我的經驗中,這實際上是一個相當罕見的情況,但它取決於設備的可用內存和用戶行爲,例如他們大量使用設備並啓動多個應用程序。

這個線程是否會過早死亡?

如果是這樣,有什麼辦法可以看到線程被殺害,並做些什麼呢?

沒有

我這麼問是因爲這個線程修改數據庫中的重要數據,如果它突然被殺,應用程序可能停止正常工作。

你所描述的可能被歸類爲'關鍵任務'。正如另外兩個答案指出的那樣,服務將是一種更強大的做事方式,因爲服務是在內存不足情況下最後被「殺死」的事情之一。使用START_REDELIVER_INTENT可能有助於恢復正在執行的操作。在任何情況下,如果您有「任務關鍵」操作,則需要設計用於完全恢復的代碼,例如使用事務以及在發生錯誤時進行回滾的可能性。

+0

當然,你可以對此做些事情。但是,一旦你允許應用程序被銷燬 - 比'onDestroy'快 - 在'onStop'設置一個線程可以輪詢的標誌,以知道應用程序可能會消失。在'onResume'中清除該標誌。線程儘可能以儘量短的塊來完成它的工作,並且如果它看到該標記,它就會自行結束。在每個塊結束時,它會更新文件進度的狀態,因此可以正確重啓。同樣在'onStop'中,直到'!thread.isAlive'或者1秒纔會返回 - 使用測試和計數器循環並且每次睡眠100毫秒,不超過10次。 – ToolmakerSteve 2016-09-22 12:52:36

+0

線程在長時間延遲後(例如服務器響應)以及執行關鍵操作(更新本地文件/數據庫)之前還需要檢查標誌。它永遠不會開始使用該標誌集的關鍵部分。只要臨界部分不超過100-200毫秒,我認爲你在實踐中是安全的。 (並不是說這是關鍵任務應用程序的好方法,但對我們大多數人來說已經足夠了)。注意我的方法的本質是在你的應用程序還活着的時候開展工作* - 通過延遲onStop來達到1第二。對於很多情況,這是所需要的。 – ToolmakerSteve 2016-09-22 12:57:34

+0

更新:我的延遲到1秒的建議太長,以至於不適合'onStop'。需要研究合適的時間 - Android對合理時間的定義是什麼。請注意,如果Android *應該有任何UI調用會有點寬鬆,那麼它就是'onStop',因爲這是應用程序的最後機會,以確保它們保留了他們所關心的任何內容。 – ToolmakerSteve 2016-09-22 13:04:58

5

這聽起來像你應該將數據庫更新移動到服務。一旦Activity進入後臺,Android會認爲它的進程可以在必要時關閉,稍後重新啓動而不會產生任何不良影響。有關更多信息,請參閱Application Fundamentals

3

我可能會挖出一箇舊線程,但沒有人提到一個重要的事情。

每次使用數據庫並修改多行時,都應該使用事務來確保數據在發生任何類型的故障時保持有效(這可能是例如線程終止,套接字異常等) 。

try{ 
     db.beginTransaction(); 

     //Do whatever you need to do...  

     db.setTransactionSuccessful(); 
    }catch(SQLiteException e){ 
     Log.e("SQLite","Error while updating rows: " + e.getMessage()); 
    }finally{ 
     db.endTransaction(); //Commit (if everything ok) or rollback (if any error occured). 
     db.close(); //Close databse; 
    } 
相關問題