標籤:androi activity棧 保留 ges 方式 ack nbsp row ase
以下所講,濃縮在 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
Android疑難雜症之KillProcess 和System.exit 無效