一节芥、Android中的進程
官方解釋
Android的系統(tǒng)架構(gòu)底層是Linux当船,上層采用的是可以運行java(其實是dex字節(jié)碼)的虛擬機(Dalvik & ART),Dalvik的核心內(nèi)容是實現(xiàn)庫(libdvm.so)钝尸,大體由C語言實現(xiàn)挎狸。依賴于Linux內(nèi)核的一部分功能——線程機制钾埂、內(nèi)存管理機制河闰,能高效使用內(nèi)存科平,并在低速CPU上表現(xiàn)出的高性能。每一個Android應(yīng)用在底層都會對應(yīng)一個獨立的Dalvik虛擬機實例姜性,其代碼在虛擬機的解釋下得以執(zhí)行匠抗。
1. 內(nèi)核進程(確切的說是內(nèi)核線程kernel thread)和用戶進程
這個是根據(jù)進程運行空間來區(qū)分的。linux常見進程與內(nèi)核線程
USER 進程當(dāng)前用戶
PID 進程ID
PPID 父進程ID
VSIZE 進程的虛擬內(nèi)存大小污抬,以KB為單位
RSS 實際占用的內(nèi)存大小,以KB為單位
PC Program Counter
NAME 進程狀態(tài)及名稱
上圖是用ChromeADB這個工具抓取的系統(tǒng)進程信息绳军,當(dāng)然也可直接用adb 的ps命名查看印机。對上圖表頭的做些解釋,PID指的是進程id
,PPID指的是parent ID也就是父進程的pid
门驾。至于VSIZE和RSS是和內(nèi)存相關(guān)的射赛,暫時不管。仔細觀察pid和ppid會發(fā)現(xiàn)規(guī)律奶是。
1.0. 進程這東西要從Linux說起楣责,Android系統(tǒng)內(nèi)核是Linux,所以Android系統(tǒng)啟動聂沙,必須先要Linux系統(tǒng)啟動秆麸。而Linux下有3個特殊的進程,idle
進程(PID = 0), init
進程(PID = 1)和kthreadd
(PID = 2)及汉,至于這三個進程的作用沮趣,可以簡答的理解為idle(PID=0)
的這個是操作系統(tǒng)boot起來后第一個線程,init
和kthreadd
都是由它通過kernel_thread
創(chuàng)建出來的坷随。
1.1. kthreadd線程由idle通過kernel_thread創(chuàng)建房铭,并始終運行在內(nèi)核空間,它的任務(wù)就是管理和調(diào)度其他內(nèi)核線程kernel_thread(內(nèi)核線程)温眉。所有內(nèi)核進程的用戶都是root缸匪,所有的內(nèi)核線程都是直接或者間接的以kthreadd為父進程 。
1.2. init進程:由idle通過kernel_thread創(chuàng)建类溢,在Linux中的定義是一個由內(nèi)核啟動的用戶級進程凌蔬, Kerner啟動后會調(diào)用/system/core/init/Init.cpp
的main()方法,然后解析/init.rc
文件豌骏,包括所有的.rc
文件龟梦,最重要的Zygote進程啟動起來。所以窃躲,init始終是第一個進程(其進程編號始終為1)计贰。在系統(tǒng)啟動完成完成后,init將變?yōu)槭刈o進程監(jiān)視系統(tǒng)其他進程蒂窒。在Android中的含義也是一樣的躁倒,是所有用戶進程的父進程荞怒。
//主要進程的創(chuàng)建(kthreadd或者fork)關(guān)系,PID給出的那幾個的PID在任何設(shè)備上都是相同的
idle(PID == 0)
|---init(PID==1)
|---servicemanager(它是整個Binder機制的守護進程)
|---zygote
|---system_server
|---com.xxx.app(每個app至少有一個進程)
|---mediaserver
|--- 秧秉。褐桌。。其他進程
|---kthreadd(PID == 2)
|---binder
|---watchdog
|---象迎。荧嵌。。其他進程
其實對于Android中進程砾淌,我們主要關(guān)心的是init進程fork出來的那幾個重要的進程
2.進程生命周期
看官網(wǎng)解釋很清楚啦撮,不再抄過來了
Android進程的重要性,劃分5級汪厨,前臺進程的重要性最高赃春,依次遞減:
前臺進程(Foreground process)
可見進程(Visible process)
服務(wù)進程(Service process)
后臺進程(Background process)
空進程(Empty process)
作用:必要時(當(dāng)資源有限時),系統(tǒng)會首先消除重要性最低的進程劫乱,然后是重要性略遜的進程织中,依此類推,以回收系統(tǒng)資源衷戈。
3. Android中開啟進程的方式
- Manifest文件給
<activity>
<service>
<receiver>
<provider>
設(shè)置屬性android:process
指定單獨進程
<!-- 假設(shè)包名為me.febsky.app -->
<activity
android:name="me.febsky.app.OtherActivity"
android:process=":remote" />
- 通過jni在native層fork一個進程出來
注:
android:process=":remote"
這行代碼翻譯一下狭吼,其實他的完整進程名為:me.febsky.app:remote
(假設(shè)當(dāng)前應(yīng)用包名為me.febsky.app)。進程名以“:”開頭的進程屬于當(dāng)前應(yīng)用的私有進程脱惰,其他應(yīng)用不可以通過SharedUID的方式和他跑在同一個進程中搏嗡;而如果沒有用“:”,直接指定android:process="me.febsky.remote"
說明開啟的這個進程是可以和別的app(這個app必須和當(dāng)前app簽名相同并且指定了sharedUID)共享的拉一。
二采盒、Android中IPC
一個app可以開啟多個進程,那么多個進程間就有可能需要通信蔚润。IPC是Inter-Process Communication(進程間通信)的首字母縮小磅氨。
1. Linux 中一些經(jīng)典的IPC
Android系統(tǒng)是基于Linux內(nèi)核的,而Linux內(nèi)核繼承和兼容了豐富的Unix系統(tǒng)進程間通信(IPC)機制嫡纠。有傳統(tǒng)的管道(Pipe)烦租、信號(Signal)和跟蹤(Trace),這三項通信手段只能用于父進程與子進程之間除盏,或者兄弟進程之間叉橱;后來又增加了命令管道(Named Pipe),使得進程間通信不再局限于父子進程或者兄弟進程之間者蠕;為了更好地支持商業(yè)應(yīng)用中的事務(wù)處理窃祝,在AT&T的Unix系統(tǒng)V中,又增加了三種稱為“System V IPC”的進程間通信機制踱侣,分別是報文隊列(Message)粪小、共享內(nèi)存(Share Memory)和信號量(Semaphore)大磺;后來BSD Unix對“System V IPC”機制進行了重要的擴充,提供了一種稱為插口(Socket)的進程間通信機制
Socket:這個東西探膊,在學(xué)java網(wǎng)絡(luò)編程的時候接觸的杠愧。它在Android中有個經(jīng)典的使用場景,在啟動一個單獨進程中的Activity或者Service的時候(Activity和Service的啟動后面再說逞壁,這里只需知道他們都是通過AMS啟動的就行了)流济,
ActivityManagerService
會通過Socket進程間通信機制,通知Zygote進程為這個應(yīng)用程序創(chuàng)建一個新的進程腌闯。
2. Android上經(jīng)典的IPC Binder
進程隔離
要說IPC袭灯,先要知道進程隔離的概念
wiki解釋:進程隔離是為保護操作系統(tǒng)中進程互不干擾而設(shè)計的一組不同硬件和軟件的技術(shù)。這個技術(shù)是為了避免進程A寫入進程B的情況發(fā)生绑嘹。 進程的隔離實現(xiàn),使用了虛擬地址空間橘茉。進程A的虛擬地址和進程B的虛擬地址不同工腋,這樣就防止進程A將數(shù)據(jù)信息寫入進程B。
Binder
這個東西并不是Google搞出來的畅卓,Binder的前身是OpenBinder擅腰,而OpenBinder的作者Dianne Hackborn現(xiàn)在在Google工作,負責(zé)Android平臺的開發(fā)工作翁潘。
Binder主要由Client(Client進程)趁冈、Server(Server進程)、ServiceManager和Binder驅(qū)動程序組成拜马。其中Client渗勘、Service和ServiceManager運行在用戶空間驼唱,而Binder驅(qū)動程序運行在內(nèi)核空間张惹。核心組件就是 Binder驅(qū)動程序了,而ServiceManager提供輔助管理的功能然遏,類似于DNS的作用扮超,無論是Client還是Service進行通信前首先要和ServiceManager取得聯(lián)系取刃。而ServiceManager是一個守護進程,負責(zé)管理Server并向Client提供查詢Server的功能出刷。
這里面很重要的一點是Binder驅(qū)動璧疗,進程a與進程b通信實際上是進程a先于Binder驅(qū)動通信,然后Binder驅(qū)動再與進程b通信的一個過程馁龟。其實進程a或者進程b與Binder的通信也是進程間通信崩侠,不過這個Binder驅(qū)動是個特殊的進程,他運行在內(nèi)核空間屁柏,至于Binder怎么就搞到了內(nèi)核空間里面去了可以搜索(Linux的動態(tài)可加載內(nèi)核模塊(Loadable Kernel Module啦膜,LKM))有送。由于進程隔離的存在,進程a打死都不可能訪問到進程b中的內(nèi)存的僧家,也就不能進行不能調(diào)用進程b中的方法,但是進程a可以通過系統(tǒng)調(diào)用
的方式訪問Binder進程(內(nèi)核進程)八拱,而內(nèi)核空間的進程能訪問用戶進程a或者進程b。了解下Linux內(nèi)核控件和用戶控件的概念
ServiceManager是由init進程通過解析init.rc文件而創(chuàng)建的肌稻,其所對應(yīng)的可執(zhí)行程序/system/bin/servicemanager,所對應(yīng)的源文件是service_manager.c爹谭,進程名為/system/bin/servicemanager枷邪∨捣玻可以把/init.rc
文件導(dǎo)出來看下,沒什么神秘的腹泌,創(chuàng)建這個進程的指令為:
service servicemanager /system/bin/servicemanager
class core
user system
group system
critical
onrestart restart healthd
onrestart restart zygote
onrestart restart media
onrestart restart surfaceflinger
onrestart restart drm