如何讓自己的Android程序永不被系統kill
相關知識:
一般來說,在Android系統中,當某進程較長時間不活動,或系統資源比較緊時,該進程可能被系統kill掉,以此來回收一些資源。Android系統會根據進程的優先級來選擇性地殺死一些進程,優先級從高到低依次是:
1. 前台進程(Foreground Process)
2. 可視進程(Visible Process)
3. 服務進程(Service Process)
4. 后台進程(Background Process)
5. 空進程(Empty Process)
1. 前台進程(Foreground Process)是指當前的活動進程,即那些有窗口、控件的,正與用戶進行交互的應用程序進程。Android會努力嘗試從其它進程回收系統資源來保持其響應。
2. 可見進程(Visible Process)是指那些可見的活動進程,但是當前它不在前台運行,不能對用戶事件作出反映。比如一個程序A正在前台運行,接着又啟動了另一個程序B,程序B的窗口把程序A的窗口完全或部分遮擋,那么,程序A現在就屬於可見進程了。一般來說,只有在系統資源十分缺乏的情況下,為了保證活動進程的運行,系統才會終止它。
3. 服務進程(Service Process)是指那些沒有可見界面的進程,它們不能直接與用戶進行交互。前台進程(通常是一個Activity)變為非活動時,會暫停運行;但服務進程可在后台保持運行,因此如果要保持進程在轉到后台后也能運行,就必需啟動一個Service。但是一旦前台進程需要資源時,Service就很容易被系統給kill掉。通常,默認情況下Service被kill掉后會自動重啟,但是重啟后並不能保證恢復先前的環境;如果不需要Service自動重啟,調用stopSelf()函數即可。
4. 后台進程(Background Process)是指不可見的,且沒有任何正在運行的服務的活動的進程。通常后台進程會比較多,Android將按“最后一個被看到,第一個終止”的方式來終止它們,從而為前台進程提供資源。
5. 對於空進程,Android為了提高系統的整體性能,經常在在應用程序的生存期結束后仍然把它們保存在內存中,當該程序被再次啟動時,可以加快啟動速度。這類進程會根據需要被定期終止。
由上可知,要想自己所寫的Service不輕易被系統在回收資源時kill掉,正常的做法是盡量提高程序的優先級,如調用startForeground(true)。因為Service啟動時默認被標記為Background,當前運行的Activity被標記為Foreground,當將Service設置為Foreground后,它的優先級就與正在運行的Activity類似,但是這也不能保證它不被系統kill。
如果我們要寫一個監控程序,監測其它程序的運行,那么該怎么辦呢?我們必需保證我們的程序不會因回收資源而kill。顯然,優先級為2-5的進程都不可靠,作為監控程序,其優先級也不可能為1。
這樣看上去,貌似沒有辦法了……別急,繼續看下面……
解決方法:
簡單地說,就是將自己寫的Service變成Core Service,即將自己寫的程序提升為系統級別的程序,這樣在任何情況下它都不會被kill掉。
要想自己寫的Service提升為Core Service,應用程序需要設置兩個標志:FLAG_PERSISTENT和FLAG_SYSTEM。
具體做法如下:
1. 設置FLAG_PERSISTENT:在AndroidManifest.xml文件中,加入android:persistent="true" ;
2. 設置FLAG_SYSTEM:將你寫的應用程序放到/system/app/目錄下即可。具體操作如下:
A. 連接adb,然后執行如下兩條命令:
adb remount
adb push your.apk /system/app/
命令adb remount是為了獲取系統目錄的臨時操作權限,然后使用push命令將自己寫的程序包上傳到系統應用程序目錄中。
B. 重啟手機。開機后,在應用列表中就可以看到你寫的程序了。
需要說明的是:系統程序不能像非系統程序那樣使用adb install your.apk來安裝apk包,我們只需要將apk包拷貝到/system/app/目錄下重啟即可。如果使用adb install的方式,那么FLAG_SYSTEM標志不會被設置,FLAG_PERSISTENT標志也將不起任何作用。
C. 如果需要卸載自己寫的系統應用程序,可執行如下命令:
adb remount
adb shell rm /system/app/yourpackage.apk
另外,還需要說明的是,如果想在模擬器中加入自己寫的系統級應用程序,好像不行,因為將apk復制到/system/app/下后,還必需重啟,但模擬器一重啟,系統目錄也將恢復初始狀態。不過網上好像有人做到了,方法也很簡單,就是將Android源碼相應地方稍改下,然后重新編譯……
現在,我們就可以讓我們的程序為所欲為了~