相信寫過android程序的朋友都遇到過希望android組件之間能夠交換信息的情況吧。大家是如何做的呢刻像?這種情況又會分為兩種不同的場景
- 通信的組件在同一種進(jìn)程中
- 通信的組件在不同的進(jìn)程中
對于第一種情況锹安,似乎并不復(fù)雜短荐,只需要想辦法讓其中一個組件獲得另一個組件的引用,然后進(jìn)行方法調(diào)用就可以了叹哭。不過需要注意的是忍宋,android框架的關(guān)鍵組件比如activity, Service, Broadcast Receiver, Content Provider對象都不是開發(fā)者在代碼里面通過new方法生成的,而是由Activity Manager Service(AMS)根據(jù)Manifest文件里面的配置信息在需要該組件的時候創(chuàng)建對象话速。這樣的話讶踪,要想取得其他組件的引用可能需要稍稍動點腦筋,比如說設(shè)置一個靜態(tài)變量來取得對另一個組件的引用泊交。
而在第二種情況乳讥,由于互相通信的組件不在同一個進(jìn)程,也就是說廓俭,它們是處在不同的虛擬機(jī)上面運(yùn)行的云石,所以它們之間是無法直接通信的。相信這點不難理解研乒,就好比兩個異地的戀人無法直接面對面交流了汹忠,就需要通過一些介質(zhì)以及渠道來進(jìn)行通信。而對于android ipc通信來說雹熬,這個介質(zhì)就是Binder了宽菜。android 框架為應(yīng)用層提供了一個IBinder接口。這個接口就是供請求IPC通信的組件使用來和另一個進(jìn)程的組件進(jìn)行通信的竿报。我們在這里以Activity和Service的通信作為例子铅乡。
1. 在Activity里調(diào)用startService()方法
AMS根據(jù)該方法里面的Intent參數(shù)以及Manifest里面的配置,創(chuàng)建對應(yīng)的Service對象烈菌,并調(diào)用相應(yīng)的生命周期方法阵幸。如果在自己定義的Service里需要和Activity進(jìn)行通信花履,就需要在該service內(nèi)部創(chuàng)建一個繼承Binder這個類的自定義Binder對象。而在這個Binder對象的構(gòu)造函數(shù)里會調(diào)用init()這個方法挚赊。這個方法內(nèi)部實際上是通過JNI調(diào)用C/C++層的init()方法生成了一個JavaBBinderHolder對象诡壁,并把該對象的指針放到自定義的Binder對象里。
2.在Activity里調(diào)用bindService()方法
在Activity里可以通過調(diào)用下面的方法來創(chuàng)建并綁定一個自定義的Service組件
<code> bindService(Intent intent,ServiceConnection conn,int flags) </code>
AMS根據(jù)方法里面的Intent參數(shù)找到對應(yīng)的Service對象荠割。而在Service類里面有個對應(yīng)的方法如下
<code>onBind(Intent intent)</code>
這個方法的返回值是一個Binder對象妹卿,而這個Binder對象也是實現(xiàn)了IBinder接口的對象,也就是說Service要想和Activity進(jìn)行通信涨共,就需要在自己這端定義一個Binder對象纽帖,然后通過onBind方法把這個對象交給AMS宠漩,然后就通過AMS來和另一個進(jìn)程的Activity進(jìn)行交流举反。AMS得到了這個Binder對象實際上就是得到了C/C++層的JavaBBinderHolder對象。當(dāng)AMS得到這個Binder對象后如何處理呢扒吁?還記得之前bindService()方法的第二個參數(shù)ServiceConnection類嗎火鼻?AMS會請求調(diào)用該對象里面onServiceConnected()方法,并根據(jù)Binder對象創(chuàng)建一個該對象的代言人對象BinderProxy對象雕崩,作為參數(shù)傳給該方法魁索。這樣在Activity里就會在自己定義的ServiceConnection對象的方法onServiceConnected()里面獲得該Binder對象,而此Binder對象就成了該Activity和Service進(jìn)行通信的一個橋梁盼铁。
3.調(diào)用IBinder.transact()方法
該方法實際上是通過底層的Binder驅(qū)動調(diào)用到C/C++層的JavaBBinder對象的tansact方法粗蔚,而該方法通過JNI來調(diào)用JAVA 層上Binder對象的execTransact()方法,并進(jìn)而調(diào)用開發(fā)者自己可以覆蓋的onTransact()方法從而達(dá)到了通信的目標(biāo)
以上就是我對android ipc通信的機(jī)制的一些梳理饶火,可能有不正確或者是不嚴(yán)謹(jǐn)?shù)牡胤脚艨兀M懈嗟娜四芙涣鳌_@也是我在簡書上的處子作肤寝,希望能通過寫文章不斷碰撞自己的思維当辐,也能夠認(rèn)識更多的朋友。