<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      寫(xiě)給Android App開(kāi)發(fā)人員看的Android底層知識(shí)(1)

      這個(gè)系列的文章一共8篇,我醞釀了很多年,參考了很多資源,查看了很多源碼,直到今天把它寫(xiě)出來(lái),也是戰(zhàn)戰(zhàn)兢兢,生怕什么地方寫(xiě)錯(cuò)了,貽笑大方。

       

       

      (一)引言

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

      再比如說(shuō),每本書(shū)都會(huì)講AIDL,但我卻從來(lái)沒(méi)用過(guò)。四大組件也是這個(gè)問(wèn)題,我只用過(guò)Activity,其它三個(gè)組件,不但沒(méi)用過(guò),甚至連它們是做什么的,都不是很清楚。

            之所以這樣,是因?yàn)槲乙恢睆氖碌氖请娚填?lèi)App開(kāi)發(fā)工作,對(duì)于這類(lèi)App,基本就是由列表頁(yè)和詳情頁(yè)組成的,所以我們每天面對(duì)的是Activity,會(huì)寫(xiě)這兩類(lèi)頁(yè)面,把網(wǎng)絡(luò)底層封裝的足夠強(qiáng)大就夠了。

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

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

       

      (二)還是引言

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

      我曾經(jīng)在微信中問(wèn)過(guò)老羅和老鄧,你們寫(xiě)的書(shū)為什么我們App開(kāi)發(fā)人員看不懂啊,他們就呵呵了,跟我說(shuō),他們的書(shū)就是寫(xiě)給ROM開(kāi)發(fā)人員看的。

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

       

      這類(lèi)知識(shí)分為兩種。

            一種是知道概念即可,就比如說(shuō)Zygote,其實(shí)App開(kāi)發(fā)人員是不需要了解Zygote的,知道有這么個(gè)東西是“孕育天地”的就夠了,類(lèi)似的還有SurfaceFlinger、WMS這些概念。

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

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

       

      (三)目錄

      我這個(gè)系列的文章,已經(jīng)寫(xiě)好了下面的內(nèi)容,會(huì)在接下來(lái)的每天發(fā)布一篇,共計(jì)8篇,看了這8篇文章,就可以邁進(jìn)Android插件化的大門(mén)了。

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

       

      Android底層知識(shí),還應(yīng)該包括以下內(nèi)容,但是和插件化關(guān)系不大,也不是我擅長(zhǎng)的領(lǐng)域,所以我只列出了大綱,沒(méi)有繼續(xù)寫(xiě)下去:

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

       

      有興趣的同學(xué),可以按照我這個(gè)思路繼續(xù)寫(xiě)下去,記得,一,少貼代碼。多畫(huà)圖,二,一定要有趣。

       

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

       

             (三)Binder

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

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

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

      注意,Client和Server是相對(duì)的。誰(shuí)發(fā)消息,誰(shuí)就是Client,誰(shuí)接收消息,誰(shuí)就是Server。

            舉個(gè)例子,兩個(gè)進(jìn)程A和B之間使用Binder通信,進(jìn)程A發(fā)消息給進(jìn)程B,那么這時(shí)候A是Binder Client,B是Binder Server;進(jìn)程B發(fā)消息給進(jìn)程A,那么這時(shí)候B是Binder Client,A是Binder Server——其實(shí)這么說(shuō)雖然簡(jiǎn)單了,但還是不太嚴(yán)謹(jǐn),我們先這么理解著。

       

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

       

       

       

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

      圖中的ServiceManager,負(fù)責(zé)把Binder Server注冊(cè)到一個(gè)容器中。

            有人把ServiceManager比喻成電話局,存儲(chǔ)著每個(gè)住宅的座機(jī)電話,還是很恰當(dāng)?shù)摹埲o李四打電話,撥打電話號(hào)碼,會(huì)先轉(zhuǎn)接到電話局,電話局的接線員查到這個(gè)電話號(hào)碼的地址,因?yàn)槔钏牡碾娫捥?hào)碼之前在電話局注冊(cè)過(guò),所以就能撥通;沒(méi)注冊(cè),就會(huì)提示該號(hào)碼不存在。

            對(duì)照著Android Binder機(jī)制,對(duì)著上面這圖,張三就是Binder Client,李四就是Binder Server,電話局就是ServiceManager,電話局的接線員在這個(gè)過(guò)程中做了很多事情,對(duì)應(yīng)著圖中的Binder驅(qū)動(dòng)

       

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

       

       

            

             注:圖中的SM也就是ServiceManager。

       

             我們看到,Client想要直接調(diào)用Server的add方法,是不可以的,因?yàn)樗鼈冊(cè)诓煌倪M(jìn)程中,這時(shí)候就需要Binder來(lái)幫忙了。

      1. 首先是Server在SM這個(gè)容器中注冊(cè)。
      2. 其次,Client想要調(diào)用Server的add方法,就需要先獲取Server對(duì)象, 但是SM不會(huì)把真正的Server對(duì)象返回給Client,而是把Server的一個(gè)代理對(duì)象返回給Client,也就是Proxy。
      3. 然后,Client調(diào)用Proxy的add方法,SM會(huì)幫他去調(diào)用Server的add方法,并把結(jié)果返回給Client。

       

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

       

             App開(kāi)發(fā)人員對(duì)Binder的掌握,這些內(nèi)容就足夠了。

       

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

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

       

             (四)AIDL

             AIDL是Binder的延伸。一定要先看懂我前面介紹的Binder,再來(lái)看AIDL。要按順序閱讀。

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

       

             AIDL中需要知道下面幾個(gè)類(lèi):

      •    IBinder
      •    IInterface
      •    Binder
      •    Proxy
      •    Stub

       

             當(dāng)我們自定義一個(gè)aidl文件時(shí)(比如MyAidl.aidl,里面有一個(gè)sum方法),Android Studio會(huì)幫我們生成一個(gè)類(lèi)文件MyAidl.java,如下圖所示:

       

       

         

      MyAidl.java這個(gè)生成文件中,包括MyAidl接口,以及Stub和Proxy兩個(gè)實(shí)現(xiàn)了MyAidl接口的類(lèi),其中Stub是定義在MyAidl接口中的,而Proxy則定義在Stub類(lèi)中。

            我曾經(jīng)很不理解,為什么不是生成3個(gè)文件,一個(gè)接口,兩個(gè)類(lèi),清晰明了。都放在一個(gè)文件中,這是導(dǎo)致很多人看不懂AIDL的一個(gè)門(mén)檻。其實(shí)Android這么設(shè)計(jì)是有道理的。當(dāng)有多個(gè)AIDL類(lèi)的時(shí)候,Stub和Proxy類(lèi)就會(huì)重名,把它們放在各自的AIDL接口中,就必須MyAidl.Stub這樣去使用,就區(qū)分開(kāi)了。

       

             對(duì)照這張圖,我們繼續(xù)來(lái)分析,Stub的sum方法是怎么調(diào)用到Proxy的sum方法?然后又調(diào)用另一個(gè)進(jìn)程的sum方法的?

             起決定意義的是Stub的asInterface方法和onTransact方法。其實(shí)這個(gè)圖沒(méi)有畫(huà)全,把完整的Binder Server也畫(huà)上,就應(yīng)該是這樣:

       

       

       

             1)先從Client看起,對(duì)于AIDL的使用者,我們這么寫(xiě)程序:

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

       

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

      •    是,則直接轉(zhuǎn)換、直接使用,接下來(lái)就跟Binder跨進(jìn)程通信無(wú)關(guān)啦;
      •    否,則把這個(gè)IBinder參數(shù)包裝成一個(gè)Proxy對(duì)象,這時(shí)調(diào)用Stub的sum方法,間接調(diào)用Proxy的sum方法。

      return new MyAidl.Stub.Proxy(obj);

            

             2)Proxy在自己的sum方法中,會(huì)使用Parcelable來(lái)準(zhǔn)備數(shù)據(jù),把函數(shù)名稱、函數(shù)參數(shù)都寫(xiě)入_data,讓_reply接收函數(shù)返回值。最后使用IBinder的transact方法,把數(shù)據(jù)就傳給Binder的Server端了。

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

            

       

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

       

             3)Server則是通過(guò)onTransact方法接收Client進(jìn)程傳過(guò)來(lái)的數(shù)據(jù),包括函數(shù)名稱、函數(shù)參數(shù),找到對(duì)應(yīng)的函數(shù),這里是sum,把參數(shù)喂進(jìn)去,得到結(jié)果,返回。

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

       

             下一篇文章要介紹的四大組件的原理,我們都可以對(duì)照著AIDL的這張圖來(lái)看,比如說(shuō),四大組件的啟動(dòng)和后續(xù)流程,都是在和ActivityManagerService(簡(jiǎn)稱AMS)來(lái)來(lái)回回的通信,四大組件給AMS發(fā)消息,四大組件就是Binder Client,而AMS就是Binder Server;AMS發(fā)消息通知四大組件,那么角色就互換。

            

             那么四大組件中,比如說(shuō)Activity,又是哪個(gè)類(lèi)扮演了Stub的角色,哪個(gè)類(lèi)扮演了Proxy的角色呢?這也是我下一篇文章要介紹的,包括AMS、四大組件各自的運(yùn)行原理。

       

             好戲即將開(kāi)始。

      posted @ 2017-05-19 10:30  包建強(qiáng)  Views(30087)  Comments(7)    收藏  舉報(bào)
      主站蜘蛛池模板: 亚洲国产亚洲综合在线尤物| 婷婷五月综合激情| 亚洲区日韩精品中文字幕| 亚洲天堂激情av在线| 亚洲精品国产av一区二区| 九九热精彩视频在线免费| 一个人在线观看免费中文www| 亚洲成av人最新无码不卡短片| 亚洲欧美日韩在线码 | 国产h视频在线观看| 日本亲近相奷中文字幕| 国产无套白浆一区二区| 国产精品三级一区二区三区 | 国内精品视频一区二区三区八戒| 国产无遮挡又黄又爽在线视频| 国产精品国产三级在线专区| 国产一区二区三区精品综合| 东乌珠穆沁旗| 保康县| 国产免费性感美女被插视频| 亚洲人妻精品中文字幕| 建宁县| 国色天香中文字幕在线视频| 国产成人精品午夜在线观看| 精品自拍自产一区二区三区| 国产成人高清亚洲综合| 插入中文字幕在线一区二区三区| 日韩精品一区二区三区久| 国产农村激情免费专区| 97久久久精品综合88久久| 日韩av中文字幕有码| 天天躁日日躁狠狠躁2018| 精品国产福利久久久| 日本熟妇XXXX潮喷视频| 亚洲人成电影在线播放| 久久婷婷大香萑太香蕉AV人 | 国产精品美女一区二区三| 成人3d动漫一区二区三区| 日韩国产欧美精品在线| 成人免费亚洲av在线| 日韩免费无码人妻波多野|