Android疑難雜症之KillProcess 和System.exit 無效


  以下所講,濃縮在 https://github.com/wytings/CrashDemo

  首先就這個名字來說,kill了process 或者 system.exit確實已經把APP殺掉了,特別是當你棧里只有一個Activity的時候,這個措施是行之有效的。但是因為Android framework的原因,在一些情況下APP會被重啟,其實更准確地來說是App被恢復了。什么情況呢?就是如果你還有未被主動關閉的Activity的時候。比如ActivityA -打開-> ActivityB —打開—ActivityC,然后再ActivityC進行system.exit或者Process.killProcess(Process.myPid());此時因為在C導致整個APP被關閉了,而A和B卻什么也沒操作就被關了,framework 層認為這是被冤殺的,所以即便是我們自己選擇去kill的,就當前的Framework 的機制來說,它認為這種主動的退出方式是一種異常退出……,所以它會竭盡全力去恢復這個APP。

  在“異常退出”的情況下,Framework會保存APP的一些狀態信息比如Activity運行棧,然后恢復一個Android應用程序時,會先從棧里面移除異常的Activity,相當於Back鍵操作。如果移除后沒有Activity則不恢復也就是“關閉成功的假象”,如果還有Activity則會恢復移除后的第一個Activity。

  來我們繼續以上面的A->B->C 打開的順序來進行說明:

  1、如果在ActivityC kill則,APP恢復時會顯示ActivityB; 

  2、如果在ActivityB kill Process則會恢復ActivityA;

  3、如果在ActivityA kill Process,由於沒有上一個Activity,則程序恢復失敗,也就是保持dead狀態。

  由於App恢復的時候,只有一個Activity,但它又保留了之前Activity棧的信息,那如何處理Back鍵呢?我們以上面的第一種情況來看,恢復了ActivityB,但是ActivityB上面還有一個ActivityA,所以恢復了ActivityB后,我們點Back鍵時,會打開ActivityA,雖然Framework本來也是想resume ActivityA,但是無奈它已經死了,所以只能重新再create一次。同理,可一直往back,直到所有的Activity都沒了。

 

  基礎信息鋪墊完了,我們現在開始針對性的說明兩個問題:1、這種異常的程序恢復會有什么缺陷?2、那到底如何徹底關閉APP?

  一、我們先來說說缺陷,首先,如果是只有一個Activity,關了就關了好像也沒什么大事,畢竟出了異常。但是如果是有多個Activity的話,恢復后就很有可能出問題。為什么?因為我們知道恢復的只有一個Activity,如果你的各種初始化參數不是在Application里面做而是在某個加載頁做的話,那么恢復這個Activity極有可能會因為調用了些沒有初始化過的類再次報錯而崩潰,這種情況也會出現在按Back鍵的時候,然后再繼續恢復一次,印象中有三次機會,三次還救不了,Framework就會說:算了,就這樣吧……

  所以,這種異常恢復最大的缺陷就是APP沒法像正常情況下一樣,完成預期的初始化流程,從而為之后的運行,增加了很多不確定性。

  二、關於如何才能徹底關閉APP。可以看看Google內部人員是怎么說的以及大家在Stackoverflow上面的討論……

  https://groups.google.com/forum/#!topic/android-developers/G_D3pKnGLt0  

  http://stackoverflow.com/questions/2033914/quitting-an-application-is-that-frowned-upon

  這里給大家截個圖~ 

 

  所以,就單個應用來說,是沒有現成的“可以自己關閉自己”的功能的……但是能做嗎?當然可以做那就是捕獲異常然后再清理掉所有的Activity再徹底關閉。這個網上都說要自己維護一個Activity序列,加個BaseActivity,然后在onCreate還有onDestroy的回調里面保存和移除……

  首先,確實要維護一個Activity的list,但是卻沒必要放在Activity里面做,完全可以放在application里面做。不知道大家有沒有記得Application有個registerActivityLifecycleCallbacks的方法?我們只需要在Application做這個就可以了,如下圖所示:

  

  然后,就可以了~以上所敘,同時還有一個偏方……  

  以上所講,濃縮在 https://github.com/wytings/CrashDemo 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM