Binder描睦、AIDL和IPC

綁定本地service并通訊

在service中定義Binder類璃赡,Binder類方法中可以訪問service的信息,在service的onbind返回binder類遥倦。

activity在它的serviceconnection.onserviceconected方法中會獲得onbind返回的binder對象谤绳,從而訪問service信息。

所以對本地service來說,binder對象就是service返回的代理對象袒哥,客戶端可以通過它反問service內(nèi)部數(shù)據(jù)缩筛,從而實現(xiàn)客戶端和service之間的通訊。

如果我們有一個接口提供服務(wù)堡称,接口一定是抽象的瞎抛,可以在service中創(chuàng)建實現(xiàn)接口的binder類,達到服務(wù)的目的却紧,剩下的和上面的相同桐臊,返回這個binder類為客戶端提供服務(wù)。

如果service想進行高消耗行為晓殊,可以繼承intentservice方法断凶,可以進行串聯(lián)耗時工作,但不支持并發(fā)挺物。

并發(fā)需要添加handle

onStartCommand返回值

如果service不在同一線程需要AIDL

首先將接口AIDL化懒浮,AIDL會自動生成java文件。

之后服務(wù)端修改binder類繼承AIDL.stub识藤,它是繼承了binder類并且實現(xiàn)了AIDL接口砚著。

客戶端通過AIDL.Stub.asInterface(service)獲得binder。

binder和service痴昧,IPC之間關(guān)系

service通信采用Ibinder通信,Ibinder也主要用于service稽穆,包含兩種,一種是本地通信赶撰,另一種是多進程通信舌镶,也就是IPC柱彻。

實現(xiàn)Ibinder可以3種方法,繼承Binder類餐胀,多進程通信可以采用AIDL和Messanger

其實AIDL也是繼承Binder類哟楷。

Messenger核心,Message以及Handler否灾。

首先服務(wù)端創(chuàng)建一個Handler卖擅,里面有handleMessage處理客戶端

之后使用回調(diào)的Handler創(chuàng)建一個Messenger,Messenger(Handler){Handle.getIMessenger()}

在onbind方法中返回底層的binder Messenger.getBinder().

客戶端的onServiceConnected通過傳過去的Ibinder創(chuàng)建Messenger(Ibinder){IMessenger.Stub.asInterface(Ibinder)},之后通過Messenger傳遞Message墨技。

使用的載體what,arg1,arg2,Bundle以及replyTo

如果需要服務(wù)端對客戶端進行回復(fù)惩阶,客戶端定義一個reHandler,利用這個Handler創(chuàng)建一個reMessenger,設(shè)置msg.replyto=reMessenger指定回復(fù)接收消息者,之后通過seMessenger發(fā)送信息扣汪,seMessenger收到信息断楷,seHandle處理,通過reMessenger.send 發(fā)送

可以看出Messenger就是一個收件地址

AIDL步驟

服務(wù)端創(chuàng)建AIDL文件包含接口崭别,在service中實現(xiàn)這些接口

客戶端綁定服務(wù)端冬筒,將onServiceConnection得到的Ibinder轉(zhuǎn)化為AIDL生成的Iinterface實例,通過實例調(diào)用方法紊遵。

Messenger和AIDL

Messenger串聯(lián)AIDL并發(fā)

service生命周期

onUnbind返回true調(diào)用onRebind,onRebind返回空值账千,但可以接收Ibinder

false調(diào)用onBind

AIDL流程

AIDL創(chuàng)建以后客戶端服務(wù)端都要有

創(chuàng)建的接口繼承了IInterface

服務(wù)端

- 重寫AIDL.Stub中的方法侥蒙,具體實現(xiàn)BookManager.stub mBookManager = new BookManager.stub() 并在內(nèi)部實現(xiàn)具體方法暗膜。也可以服務(wù)端新建繼承Stub類

- onBind中返回AIDL.Stub

客戶端

AIDL.Stub.asInterface(service)獲得binder。

AIDL源碼分析

客戶端分析

asInterface傳參Ibinder返回stub

先判定是否在同一進程鞭衩,如果是学搜,返回服務(wù)端AIDL的interface對象本身,就是Stub论衍,否則返回Stub.proxy

proxy獲取換過去的Ibinder mremote

- 生成_data _reply數(shù)據(jù)流data.writeInterfaceToken(DESCRIPOR)

- 調(diào)用mremote.transact傳給服務(wù)端并請求服務(wù)端調(diào)用指定方法瑞佩。調(diào)用的是Stub中的實現(xiàn)方法。

- 接收reply數(shù)據(jù)流

服務(wù)端分析

1獲取客戶端傳過來數(shù)據(jù)坯台,根據(jù)ID執(zhí)行響應(yīng)操作

2傳過來數(shù)據(jù)data取出來炬丸,調(diào)用本地方法。data.enforceInterface(DESCRIPTOP)

3回傳數(shù)據(jù)寫入reply

服務(wù)端調(diào)用客戶端方法

提供一個AIDL的客戶端方法的接口蜒蕾,因為AIDL中無法使用普通接口

在客戶端中對方法進行具體實現(xiàn)

Binder連接池

- 為連接池創(chuàng)建queryBinder接口

- 為連接池創(chuàng)建遠程service稠炬,并實現(xiàn)queryBinder,返回需要具體的繼承Stub的Binder對象

使用

- 連接service咪啡,獲取Binderpoor

- 獲得連接池

- 通過queryBinder獲取Binder

注意事項

- onTransact返回false首启,客戶端的請求會失效。

- 客戶端線程會被掛起直至服務(wù)端進程返回數(shù)據(jù)撤摸,所以耗時方法不應(yīng)在UI線程執(zhí)行毅桃。

- 服務(wù)端的Binder 方法在Binder線程池中褒纲,所以應(yīng)采用同步方式。

- Binder意外死亡钥飞,需要重新連接服務(wù)莺掠,兩種方法,第一種給Binder設(shè)置死亡代理读宙,linkToDeath(DeathRecipient{binderDied{unlinkToDeath}})設(shè)置死亡代理汁蝶,死亡會回調(diào)客戶端Binder線程池中binderDied方法。第二種方法论悴,在onServiceDisconnected重連掖棉,在客戶端中UI線程中被回調(diào)。另外可以設(shè)置isBinderAlive檢查Binder是否死亡

- CopyOnWriteArrayList支持并發(fā)讀寫

- RemoteCallbackList 系統(tǒng)專門提供用于刪除跨進程listener接口 使用原因 多次跨進程傳輸客戶端的同一個對象會在服務(wù)端生成不同對象膀估,但新生成對象底層Binder對象是同一個

- 客戶端調(diào)用遠程服務(wù)的方法幔亥,被調(diào)用的方法運行在服務(wù)端的Binder線程池中,Binder線程池可以執(zhí)行大量耗時工作察纯,如果某個遠程方法是耗時的帕棉,避免在UI線程中調(diào)用。遠程服務(wù)端調(diào)用客戶端中方法饼记,被調(diào)用方法運行在客戶端Binder線程池中香伴,不能訪問UI內(nèi)容,如果要訪問客戶端UI具则,需要使用Handler切換到UI線程

- 在AIDL中使用權(quán)限驗證功能即纲,1在onBind中進行驗證,使用permission博肋,返回null2在服務(wù)端onTransact方法中返回false,可以通過permission或UidPid驗證

IPC方式

1使用Bundle低斋,只能放入序列化數(shù)據(jù)

2使用文件共享,避免數(shù)據(jù)同步匪凡,妥善處理并發(fā)讀寫膊畴。不建議SharedPreferences,緩存在內(nèi)存中病游,多進程模式下讀寫不可靠唇跨,會丟失數(shù)據(jù)。

3Messenger

4AIDL

5ContentProvider

底層Binder

通過ContentProvider跨進程通信

- ContentProvider六個方法衬衬,onCreat運行在主線程买猖,其他getTypeCRUD運行在Binder線程池中,每次的線程都不一樣

4Socket

流勢套接字Tcp 用戶數(shù)據(jù)報套接字UDP

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末佣耐,一起剝皮案震驚了整個濱河市政勃,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌兼砖,老刑警劉巖奸远,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件既棺,死亡現(xiàn)場離奇詭異,居然都是意外死亡懒叛,警方通過查閱死者的電腦和手機丸冕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來薛窥,“玉大人胖烛,你說我怎么就攤上這事∽缑裕” “怎么了佩番?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長罢杉。 經(jīng)常有香客問我趟畏,道長,這世上最難降的妖魔是什么滩租? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任赋秀,我火速辦了婚禮,結(jié)果婚禮上律想,老公的妹妹穿的比我還像新娘猎莲。我一直安慰自己,他們只是感情好技即,可當(dāng)我...
    茶點故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布著洼。 她就那樣靜靜地躺著,像睡著了一般姥份。 火紅的嫁衣襯著肌膚如雪郭脂。 梳的紋絲不亂的頭發(fā)上年碘,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天澈歉,我揣著相機與錄音,去河邊找鬼屿衅。 笑死埃难,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的涤久。 我是一名探鬼主播涡尘,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼响迂!你這毒婦竟也來了考抄?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤蔗彤,失蹤者是張志新(化名)和其女友劉穎川梅,沒想到半個月后疯兼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡贫途,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年吧彪,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片丢早。...
    茶點故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡姨裸,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出怨酝,到底是詐尸還是另有隱情傀缩,我是刑警寧澤,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布农猬,位于F島的核電站扑毡,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏盛险。R本人自食惡果不足惜瞄摊,卻給世界環(huán)境...
    茶點故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望苦掘。 院中可真熱鬧换帜,春花似錦、人聲如沸鹤啡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽递瑰。三九已至祟牲,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間抖部,已是汗流浹背说贝。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留慎颗,地道東北人乡恕。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像俯萎,于是被迫代替她去往敵國和親傲宜。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,697評論 2 351

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