Android 進程常駐(1)----開篇

這是一個輕量級的庫,配置幾行代碼,就能夠實如今android上實現進程常駐,也就是在系統強殺下,以及360獲取root權限下,clean master獲取root權限下都沒法殺死進程android

支持系統2.3到6.0git

支持大部分設備,包括三星,華爲,oppo,nexus,魅族等等github

能夠簡單對開機廣播進行保護shell


github地址:安全

https://github.com/Marswin/MarsDaemonide

原理分析:性能

Android 進程常駐(0)----MarsDaemon使用說明
優化

Android 進程常駐(1)----開篇
ui

Android 進程常駐(2)----細數利用android系統機制的保活手段
spa

Android 進程常駐(3)----native保活5.0如下方案推演過程以及代碼詳述

Android 進程常駐(4)----native保活5.0以上方案推演過程以及代碼詳述

Android 進程常駐(5)----開機廣播的簡單守護以及總結



正文:



Android 進程常駐,顧名思義,就是要讓咱們的進程在內存中永遠存在,換句話說就是進程保活,臭不要臉的說法就是關不了,殺不死,幹不掉。這不是耍流氓,是不少場景若是要想爲用戶服務,就必須有一個進程常駐,以便在特定的時候作特定的事情。好比在Android中,許多BroadcastReceiver事件不支持靜態註冊,也就是說若是我想接受屏幕開關的系統廣播,必需要在進程中動態註冊,若是沒有一個常駐進程,那麼鎖屏應用就沒法正常爲用戶服務;另外IM類應用,也須要在後臺維護一個長連接,以便於在最及時的時間裏將信息傳達給用戶。誠然,但凡進程常駐內存,不管怎樣優化,都會或多或少的增長一些額外的性能開支,在爲用戶最負責任的服務,最高品質的體現咱們的價值的前提下,咱們要儘量減小內存和電量的消耗,這個後面會說到。這裏吐槽一下一些無良開發者,爲一些徹底沒必要要的業務常駐一個進程,這樣只會加快用戶卸載的速度,最讓人忍受不了的是,代碼低效,保活無力,還特麼燒電!最後我想說的是,不以服務用戶爲目的的內存常駐都是耍流氓!

閒淡少扯。

進入正題。

知己知彼,方能百戰不殆。要想保活,就要先知道是怎麼死的。死因大概有三:第一被系統乾死;第二被第三方安全軟件乾死,好比知名的有奇虎360、CleanMaster(固然包括是否有root權限,有無root天壤之別);第三就是被用戶手動乾死,好比小米自帶的系統一鍵清理、手機設置裏應用管理器的ForceClose。下面開始分析。

Android系統是基於Linux系統,他繼承了Linux的內存管理策略,即進程退出並不會馬上殺死,而是在系統內存吃緊的時候再來按照優先級殺掉進程,這不一樣於微軟的Windows,Windows在進程退出的同時必定殺掉進程,將內存釋放乾淨。一個是儘量的充分利用內存,來提升再次開啓進程的速度;一個是放着大塊大塊的內存寧肯永遠閒置也不用。做爲一個移動設備的操做系統,Android繼承前者無可厚非,他繼承了Linux的lowmemorykiller。

在系統的/sys/module/lowmemorykiller/parameters目錄下,咱們cat文件minfree,他記錄了6個數字,分別對應了六個進程類型的斬首的閥值(單位爲page,1page=4kb)。如圖


三星note3

三星s5


六個進程類型從左往右分別爲:ForegroundProgress/VisibleProgress/SecondaryService/HiddenProgress/ContentProvider/EmptyProgress

一、前臺進程(好比正在顯示的activity所在的進程)

二、可見進程(好比輸入法進程)

三、次要服務進程

四、隱藏進程

五、內容提供者進程

六、空進程

這些數字所表明到所謂斬首閥值,表明系統剩餘內存達到他們對應的閥值的時候,就開始操刀斬首對應的進程了,因此在上圖能夠看出,當s5剩餘內存爲56320*4kb約等於200m的時候開始清理空進程,而note3則是120m纔開始。


六個進程類型定義於kernel層,在framework層,作了更細緻的劃分,以便於進程查看管理。他們定義在com.android.server.am.ActivityManager.RunningProgressInfo中,以下圖。開發者可使用Android 開放的API拿到對應進程的RunningProgressInfo來查看他的importance。




當斬首開始,一樣一個級別的進程有好多個,究竟先殺誰呢?比比誰的哈希值大就先殺誰?固然不是。Kernel層定義了六個進程類型對應的adj,他們定義在/sys/module/lowmemorykiller/parameters/adj


數值越大越容易被殺,同時Android 增長了兩個Linux中沒有的進程adj,他們分別是CORE_SERVER_ADJ=-十二、SYSTEM_ADJ = -16,定義在ActivityManagerService中。咱們能夠在在shell下ps查看全部進程,找到對應進程pid,而後再/proc/pid/oom_adj下查看對應進程的adj。


上圖是在手機三星s5上,系統爲android5.1,應用中在MainActivity啓動了兩個Service,而且兩個Service 都在menifest中定義爲其餘進程


從上到下分別爲activity的進程,正常的service進程,設置爲前臺service的service進程。

而後分別到對應的進程號pid的目錄下查看對應的adj。

每次cat都對應了ui上的操做:

從上往下分別是:

應用安裝完畢,5.1系統會彈出一個activity來確認應用權限,此時咱們的activity爲onstrop狀態(5114進程第一次cat

關閉權限確認的界面,此時咱們的activity爲onresume狀態(5114進程第二次cat

點擊back鍵,咱們的activity爲ondestroy狀態,且該進程內無其餘運行組件(5114進程第三次cat

正常的service進程,沒有作任何設置(5155進程cat

設置爲前臺service的進程(5156進程cat)

最後根據進程的oom_score來決定究竟斬誰的首,那麼oom_score是怎麼算出來的呢?他正是經過剛纔講的oom_adj、佔用內存大小、啓動時間等加權算出oom得分,得分最高者立斬。那麼oom_adj的值又是誰在維護他呢,activity的生命週期是隻有framework才知道,kernel不知道,因此這件事天然是由總管家ActivityManagerService來作


然而真正的lowmemorykiller倒是在kernel層,源碼位於Android 源碼/kernel/drivers/staging/android/lowmemorykiller

如下是具體殺進程的代碼片斷



是的,信號。固然沒這麼簡單!後面再說


那麼第三方安全軟件是怎麼殺進程的呢?首先系統提供的方法就有


註釋講的明白,會在過會兒須要的時候再啓起來,只需配置一個start_stick就殺不死,這個太low。

那麼來看看framework本身是怎麼管理的,殺掉前臺進程之外的全部進程


向下跟代碼


繼續


與killProcessQuiet不一樣的是killProcess,發送的信號不一樣


經過反射,須要root權限

再看看系統設置裏面的force close(話說百分之九十五以上的應用都難逃系統的fc)是怎麼殺掉進程的呢?


看到了嗎?第一段註釋,會殺掉全部和該packageName共享uid的進程,會取消掉該進程全部鬧鐘!百分之九十五的保活難逃此劫,可是marsdaemon能夠作到,這裏先賣個關子,之後慢慢講,正在整理代碼,上傳github。


經過fc殺掉的進程在packagemanager中還會設置一個flag,以致於以後全部的廣播都會將你過濾掉,防止你被系統的廣播呼起,直到用戶手動點擊icon啓動該應用,該flag纔會置爲false。固然這隻針對系統廣播,咱們本身發的廣播只要加入一個flag值就ok了。

force close 方法這麼屌,第三方能不能用呢?咱們根據這個方法要求的permission,在源碼中找到該permission的定義


須要系統簽名!因此第三方只能呵呵?可是!

可是!勞動人民的智慧是無窮盡的,最近好多第三方安全軟件,推出了免root功能,除了利用短暫的系統漏洞侵入系統外,都是利用了android的AccessibilityHelper,這個功能初衷是幫助老年人或者視力有障礙的人羣進行模擬點擊操做,只要應用通過用戶受權,就能夠獲取當前屏幕的全部控件以及空間上的信息,模擬手指觸屏操做。因而乎,所謂的免root是讓你給他們受權,而後他們給你在手機上點點點,點到settings中找到對應package點擊force close,被用戶看到你在操控他的手機固然很差,因而上面蓋一個window當遮羞布,給你顯示個進度條,後面不停點點點,就是這樣。有空再發一下AccessibilityHelper 的demo。

此外有了root權限,能夠直接用代碼在terminal中調用kill -9 pid命令,等同於發送一個kill信號來殺死進程。

說了這麼多,第三方的安全軟件進程清理到底具體採用了哪一種手段,以及使用了其餘我不知道的方法。可是歸根結底都是一個kill,因此咱們只關心進程死掉的一瞬間。


此文寫的越到後面越亂,由於發現如今已經凌晨三點十分,明天還要上班。本文只是鋪墊,真正的進程常駐重頭戲在native上,未完待續。

相關文章
相關標籤/搜索