寫給Android App開發(fā)人員看的Android底層知識(1)

這個系列的文章一共8篇苛白,我醞釀了很多年,參考了很多資源焚虱,查看了很多源碼购裙,直到今天把它寫出來,也是戰(zhàn)戰(zhàn)兢兢鹃栽,生怕什么地方寫錯了躏率,貽笑大方。

(一)引言

早在我還是Android菜鳥的時候,有很多技術(shù)我都不太明白禾锤,也都找不到答案私股,比如apk是怎么安裝的,比如資源是怎么加載的恩掷。

再比如說倡鲸,每本書都會講AIDL,但我卻從來沒用過黄娘。四大組件也是這個問題峭状,我只用過Activity逼争,其它三個組件,不但沒用過誓焦,甚至連它們是做什么的,都不是很清楚杂伟。

之所以這樣,是因為我一直從事的是電商類App開發(fā)工作赫粥,對于這類App观话,基本就是由列表頁和詳情頁組成的频蛔,所以我們每天面對的是Activity,會寫這兩類頁面秦叛,把網(wǎng)絡(luò)底層封裝的足夠強大就夠了。

絕大多數(shù)App開發(fā)人員挣跋,都是如此。

但直到接觸Android的插件化編程和熱修復(fù)技術(shù)浆劲,才發(fā)現(xiàn)只掌握上述這些技術(shù)是遠(yuǎn)遠(yuǎn)不夠的哀澈。

(二)還是引言

市場上有很多介紹Android底層的書籍,網(wǎng)上也有很多文章割按,但大都是給ROM開發(fā)人員看的膨报,動輒貼出幾頁代碼,不適合App開發(fā)人員去閱讀學(xué)習(xí)。

我曾經(jīng)在微信中問過老羅和老鄧现柠,你們寫的書為什么我們App開發(fā)人員看不懂啊院领,他們就呵呵了,跟我說够吩,他們的書就是寫給ROM開發(fā)人員看的比然。

于是,這幾年來周循,我一直在尋找這樣一類知識强法,App開發(fā)人員看了能有助于他們更好的編寫App程序,而又不需要知道太多這門技術(shù)底層的代碼實現(xiàn)湾笛。

這類知識分為兩種饮怯。

一種是知道概念即可,就比如說Zygote嚎研,其實App開發(fā)人員是不需要了解Zygote的蓖墅,知道有這么個東西是"孕育天地"的就夠了,類似的還有SurfaceFlinger临扮、WMS這些概念论矾。

還有一種是需要知道內(nèi)部原理,就比如說Binder公条。關(guān)于Binder的介紹鋪天蓋地拇囊,但對于我們App開發(fā)人員,需要了解的是它的架構(gòu)模型靶橱,只要有Client和Server寥袭,以及SM就足夠了。

四大組件的底層通信機制都是基于Binder的关霸,我們需要知道每個組件中传黄,分別是哪些類扮演了Binder Client,哪些類扮演了Binder Server队寇。知道這些概念膘掰,有助于我們App開發(fā)人員進(jìn)行插件化編程。

(三)目錄

我這個系列的文章佳遣,已經(jīng)寫好了下面的內(nèi)容识埋,會在接下來的每天發(fā)布一篇,共計8篇零渐,看了這8篇文章窒舟,就可以邁進(jìn)Android插件化的大門了。

  • Binder
  • AIDL
  • AMS
  • Activity
  • Service
  • ContentProvider
  • 匿名共享內(nèi)存
  • BroadcastReceiver
  • PMS及App安裝過程

Android底層知識诵盼,還應(yīng)該包括以下內(nèi)容惠豺,但是和插件化關(guān)系不大,也不是我擅長的領(lǐng)域洁墙,所以我只列出了大綱热监,沒有繼續(xù)寫下去:

  • View和ViewGroup
  • Message、Looper和Handler
  • 權(quán)限管理
  • Android SDK工具內(nèi)部原理

有興趣的同學(xué)羹呵,可以按照我這個思路繼續(xù)寫下去疗琉,記得,一凑耻,少貼代碼柠贤。多畫圖,二邻吭,一定要有趣宴霸。

接下來就詳細(xì)講那些App開發(fā)人員需要知道的Android底層知識。

(三)Binder

Binder是為了解決跨進(jìn)程通信畸写。

關(guān)于Binder的文章實在是太多了氓扛,每篇文章都能從Java層講到C++層,App開發(fā)人員其實是沒必要了解這么多內(nèi)容的千所。我們看對App開發(fā)有用的幾個點:

1)首先蒜埋,Binder分為Client和Server兩個進(jìn)程。

注意黑界,Client和Server是相對的朗鸠。誰發(fā)消息础倍,誰就是Client,誰接收消息忆家,誰就是Server德迹。

舉個例子,兩個進(jìn)程A和B之間使用Binder通信胳搞,進(jìn)程A發(fā)消息給進(jìn)程B,那么這時候A是Binder Client筷转,B是Binder Server悬而;進(jìn)程B發(fā)消息給進(jìn)程A,那么這時候B是Binder Client袭蝗,A是Binder Server——其實這么說雖然簡單了艰躺,但還是不太嚴(yán)謹(jǐn),我們先這么理解著左电。

2)其次篓足,我們看下面這個圖(摘自田維術(shù)的博客)闰蚕,基本說明白了Binder的組成解構(gòu):

圖中的IPC就是進(jìn)程間通信的意思没陡。

圖中的ServiceManager索赏,負(fù)責(zé)把Binder Server注冊到一個容器中潜腻。

有人把ServiceManager比喻成電話局器仗,存儲著每個住宅的座機電話,還是很恰當(dāng)?shù)耐埂埲o李四打電話轨香,撥打電話號碼弹沽,會先轉(zhuǎn)接到電話局,電話局的接線員查到這個電話號碼的地址炸渡,因為李四的電話號碼之前在電話局注冊過丽已,所以就能撥通;沒注冊吼畏,就會提示該號碼不存在嘁灯。

對照著Android Binder機制丑婿,對著上面這圖,張三就是Binder Client秒旋,李四就是Binder Server诀拭,電話局就是ServiceManager,電話局的接線員在這個過程中做了很多事情细卧,對應(yīng)著圖中的Binder驅(qū)動

3)接下來我們看Binder通信的過程,還是摘自田維術(shù)博客的一張圖:

注:圖中的SM也就是ServiceManager魄健。

我們看到插勤,Client想要直接調(diào)用Server的add方法农尖,是不可以的盛卡,因為它們在不同的進(jìn)程中筑凫,這時候就需要Binder來幫忙了。

1. 首先是Server在SM這個容器中注冊滓技。
?2. 其次棚潦,Client想要調(diào)用Server的add方法,就需要先獲取Server對象叠必, 但是SM不會把真正的Server對象返回給Client妹窖,而是把Server的一個代理對象返回給Client,也就是Proxy共苛。
?3. 然后谒麦,Client調(diào)用Proxy的add方法绕德,SM會幫他去調(diào)用Server的add方法,并把結(jié)果返回給Client踪蹬。

以上這3步,Binder驅(qū)動出了很多力跃捣,但我們不需要知道Binder驅(qū)動的底層實現(xiàn),涉及到C++的代碼了——把有限的時間去做更有意義的事情酣胀。

App開發(fā)人員對Binder的掌握闻镶,這些內(nèi)容就足夠了丸升。

是時候總結(jié)一波了:

1. 學(xué)習(xí)Binder,是為了更好的理解AIDL墩剖,基于AIDL模型夷狰,進(jìn)而了解四大組件的原理。
?2. 理解了Binder蒲障,再看AMS和四大組件的關(guān)系揉阎,就像是Binder的兩個進(jìn)程Server和Client通信背捌。

(四)AIDL

AIDL是Binder的延伸。一定要先看懂我前面介紹的Binder坑赡,再來看AIDL么抗。要按順序閱讀。

Android系統(tǒng)中很多系統(tǒng)服務(wù)都是aidl螟加,比如說剪切板捆探。舉這個例子,是為了讓App開發(fā)人員知道AIDL無處不在黍图,和我們距離非常近。

AIDL中需要知道下面幾個類:

  • IBinder
  • IInterface
  • Binder
  • Proxy
  • Stub

當(dāng)我們自定義一個aidl文件時(比如MyAidl.aidl剖张,里面有一個sum方法)修械,Android Studio會幫我們生成一個類文件MyAidl.java检盼,如下圖所示:

MyAidl.java這個生成文件中吨枉,包括MyAidl接口貌亭,以及Stub和Proxy兩個實現(xiàn)了MyAidl接口的類认臊,其中Stub是定義在MyAidl接口中的,而Proxy則定義在Stub類中剧腻。

我曾經(jīng)很不理解涂屁,為什么不是生成3個文件拆又,一個接口,兩個類栈源,清晰明了竖般。都放在一個文件中,這是導(dǎo)致很多人看不懂AIDL的一個門檻制轰。其實Android這么設(shè)計是有道理的。當(dāng)有多個AIDL類的時候男杈,Stub和Proxy類就會重名伶棒,把它們放在各自的AIDL接口中彩库,就必須MyAidl.Stub這樣去使用,就區(qū)分開了宛渐。

對照這張圖眯搭,我們繼續(xù)來分析,Stub的sum方法是怎么調(diào)用到Proxy的sum方法寇蚊?然后又調(diào)用另一個進(jìn)程的sum方法的棍好?

起決定意義的是Stub的asInterface方法和onTransact方法。其實這個圖沒有畫全扒怖,把完整的Binder Server也畫上业稼,就應(yīng)該是這樣:

1)先從Client看起盼忌,對于AIDL的使用者,我們這么寫程序:

MyAidl.Stub.asInterface(某IBinder對象).sum(1, 2); //最好在執(zhí)行sum方法前判空谦纱。

asInterface方法的作用是判斷參數(shù)——也就是IBinder對象,和自己是否在同一個進(jìn)程:

  • 是川慌,則直接轉(zhuǎn)換梦重、直接使用,接下來就跟Binder跨進(jìn)程通信無關(guān)啦降瞳;
  • 否,則把這個IBinder參數(shù)包裝成一個Proxy對象挣饥,這時調(diào)用Stub的sum方法扔枫,間接調(diào)用Proxy的sum方法锹安。

return new MyAidl.Stub.Proxy(obj);

2)Proxy在自己的sum方法中,會使用Parcelable來準(zhǔn)備數(shù)據(jù)忍宋,把函數(shù)名稱话速、函數(shù)參數(shù)都寫入_data泊交,讓_reply接收函數(shù)返回值柱查。最后使用IBinder的transact方法,把數(shù)據(jù)就傳給Binder的Server端了研乒。

mRemote.transact(Stub.TRANSACTION_addBook, _data, _reply, 0); //這里的mRemote就是asInterface方法傳過來的obj參數(shù)

———————我是Binder分界線—————

3)Server則是通過onTransact方法接收Client進(jìn)程傳過來的數(shù)據(jù)淋硝,包括函數(shù)名稱谣膳、函數(shù)參數(shù),找到對應(yīng)的函數(shù)继谚,這里是sum,把參數(shù)喂進(jìn)去芽世,得到結(jié)果济瓢,返回。

所以onTransact函數(shù)經(jīng)歷了讀數(shù)據(jù)-->執(zhí)行要調(diào)用的函數(shù)-->把執(zhí)行結(jié)果再寫數(shù)據(jù)的過程涨共。

下一篇文章要介紹的四大組件的原理宠漩,我們都可以對照著AIDL的這張圖來看,比如說火鼻,四大組件的啟動和后續(xù)流程雕崩,都是在和ActivityManagerService(簡稱AMS)來來回回的通信,四大組件給AMS發(fā)消息粗蔚,四大組件就是Binder Client饶火,而AMS就是Binder Server肤寝;AMS發(fā)消息通知四大組件,那么角色就互換鲤看。

那么四大組件中,比如說Activity找筝,又是哪個類扮演了Stub的角色慷吊,哪個類扮演了Proxy的角色呢?這也是我下一篇文章要介紹的陆赋,包括AMS、四大組件各自的運行原理攒岛。

好戲即將開始灾锯。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市吵聪,隨后出現(xiàn)的幾起案子吟逝,更是在濱河造成了極大的恐慌赦肋,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件囱井,死亡現(xiàn)場離奇詭異庞呕,居然都是意外死亡程帕,警方通過查閱死者的電腦和手機骆捧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進(jìn)店門敛苇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來枫攀,“玉大人株茶,你說我怎么就攤上這事∑羰ⅲ” “怎么了?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵卧抗,是天一觀的道長社裆。 經(jīng)常有香客問我,道長标沪,這世上最難降的妖魔是什么嗜傅? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任磺陡,我火速辦了婚禮币他,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘彰阴。我一直安慰自己尿这,他們只是感情好射众,可當(dāng)我...
    茶點故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布晃财。 她就那樣靜靜地躺著断盛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪伙菜。 梳的紋絲不亂的頭發(fā)上贩绕,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天淑倾,我揣著相機與錄音,去河邊找鬼假瞬。 笑死迂尝,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的琴许。 我是一名探鬼主播榜田,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼箭券,長吁一口氣:“原來是場噩夢啊……” “哼辩块!你這毒婦竟也來了荆永?” 一聲冷哼從身側(cè)響起具钥,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤骂删,失蹤者是張志新(化名)和其女友劉穎桃漾,沒想到半個月后拟逮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡凭迹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年嗅绸,在試婚紗的時候發(fā)現(xiàn)自己被綠了鱼鸠。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蚀狰。...
    茶點故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡职员,死狀恐怖麻蹋,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情焊切,我是刑警寧澤扮授,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站专肪,受9級特大地震影響刹勃,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜嚎尤,卻給世界環(huán)境...
    茶點故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一深夯、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧诺苹,春花似錦咕晋、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽质蕉。三九已至,卻和暖如春兑宇,著一層夾襖步出監(jiān)牢的瞬間隶糕,已是汗流浹背枚驻。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留铃拇,地道東北人。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像磷雇,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子崩掘,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,828評論 2 345

推薦閱讀更多精彩內(nèi)容