android 活动销毁不了,即使活动已经销毁,AsyncTask也不会停止
我想添加一個信息補充,并給出一個指向庫或2的指針,可以用于長時間運行的AsyncTask,甚至可以用于面向網絡的asynctasks。
AsyncTasks專為在后臺執行操作而設計。是的,您可以使用該cancel方法停止它。當您從Internet下載內容時,我強烈建議您在IO阻塞狀態下處理您的線程。您應按照以下方式組織下載:public?void?download()?{
//get?the?InputStream?from?HttpUrlConnection?or?any?other
//network?related?stuff
while(?inputStream.read(buffer)?!=?-1?&&?!Thread.interrupted()?)?{
//copy?data?to?your?destination,?a?file?for?instance
}
//close?the?stream?and?other?resources}
使用該Thread.interrupted標志將幫助您的線程正確地退出阻塞io狀態。您的線程將更靈敏地調用該cancel方法。
AsyncTask設計缺陷
但如果您的AsyncTask持續時間過長,那么您將面臨兩個不同的問題:活動與活動生命周期密切相關,如果活動中斷,您將無法獲得AsyncTask的結果。的確,是的,你可以,但這將是粗糙的方式。
AsyncTask沒有很好的文檔記錄。一個天真但直觀的實現和使用asynctask可能很快導致內存泄漏。
我想介紹的庫RoboSpice使用后臺服務來執行這種請求。它專為網絡請求而設計。它提供了其他功能,例如自動緩存請求的結果。
這就是為什么AsyncTasks對于長時間運行的任務不利的原因。以下推理是對RoboSpice動機的改編:適用于解釋為什么使用RoboSpice滿足Android平臺需求的應用程序。
AsyncTask和Activity生命周期
AsyncTasks不遵循Activity實例的生命周期。如果在Activity中啟動AsyncTask并旋轉設備,則將銷毀Activity并創建新實例。但AsyncTask不會死。它會繼續生存直到它完成。
完成后,AsyncTask將不會更新新Activity的UI。實際上,它更新了之前不再顯示的活動實例。這可能導致java.lang.IllegalArgumentException類型的異常:如果您使用findViewById來檢索Activity內的視圖,則View不會附加到窗口管理器。
內存泄漏問題
將AsyncTasks創建為活動的內部類非常方便。由于AsyncTask需要在任務完成或正在進行時操縱Activity的視圖,使用Activity的內部類似乎很方便:內部類可以直接訪問外部類的任何字段。
然而,這意味著內部類將在其外部類實例上保存一個不可見的引用:Activity。
從長遠來看,這會產生內存泄漏:如果AsyncTask持續很長時間,它會使活動保持“活著”,而Android則希望擺脫它,因為它無法再顯示。該活動不能被垃圾收集,這是Android在設備上保留資源的核心機制。
您的任務進度將丟失
您可以使用一些變通方法來創建長時間運行的異步任務,并根據活動的生命周期管理其生命周期。您可以在活動的onStop方法中取消AsyncTask,也可以讓異步任務完成,而不是松開其進度并將其重新鏈接到下一個活動實例。
這是可能的,我們展示了RobopSpice的動機,但它變得復雜,而且代碼并不是真正的通用。此外,如果用戶離開活動并返回,您仍將失去任務的進度。Loaders也出現了同樣的問題,盡管它與上面提到的重新鏈接解決方法的AsyncTask相比更簡單。
使用Android服務
最好的選擇是使用服務來執行長時間運行的后臺任務。這正是RoboSpice提出的解決方案。同樣,它專為網絡設計,但可以擴展到非網絡相關的東西。該庫具有大量功能。
你可以通過信息圖表在不到30秒的時間內了解它。
對于長時間運行的操作使用AsyncTasks確實是一個非常糟糕的主意。然而,它們適用于短期生活,例如在1或2秒后更新視圖。
我鼓勵您下載RoboSpice Motivations應用程序,它真正深入地解釋了這一點,并提供了有關網絡相關內容的不同方法的示例和演示。
如果您正在為非網絡相關任務(例如沒有緩存)尋找RoboSpice的替代方案,您還可以查看Tape。
總結
以上是生活随笔為你收集整理的android 活动销毁不了,即使活动已经销毁,AsyncTask也不会停止的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Win10玩GTA5草从掉帧优化教程
- 下一篇: 咪咕视频好用吗(上的咪咕视频)