Messenger: 基于消息的 跨進程通信(完結)

基于 Handler 的 IPC 進程間通信, android 提供了一種 組件 service, 可以 作為單獨的 進程 為 應用程序 提供服務.?

大家都知道 handler 是 用來完成 線程間的 通信, 但其實 Handler 提供了 進程間 通信的支持.?

一. 先舉個 例子:

一. ? service 端代碼為: ?

? ? ? 在處理 客戶端 請求的時候我們 可以看出來 進程 交互的 非 基本數(shù)據(jù)都被 存儲到了 Bundle 中, 因此 如果我們 想傳一些 定義的 對象, 可以讓這些 對象 實現(xiàn) Parcelable接口, 以便 放到 Bundle 中 , 進行進程間 交互.

? ? ?第二點 可以注意的是:當 Service 進程 處理好 請求后, 會 封裝好 要返回的數(shù)據(jù), 調(diào)用 message 的 replyTo 這個 Messenger 對象的 send 方法 把 Service 進程端 封裝的 Message 傳給 客戶端. ( 下面會解釋 replyTo 是啥).


二. ? ?客戶端 代碼又 如下:

1. 創(chuàng)建 ServiceConnection 對象: ?通過 onServiceConnected 方法, 我們 創(chuàng)建了 可以向 Service 發(fā) 請求的 Messenger 對象 ,其 引用為 server.


2. ?于是乎, 我們 可以 調(diào)用 server 向 前面提到的 Service 進程 發(fā)出請求, 我們 創(chuàng)建一個 Message 消息 把 命令字 賦值給 msg.what, 然后 就可以 調(diào)用 server.send() 方法 把 這個 Message 發(fā)給 Service 進程處理, 但 如果 Service 進程想 通知 客戶端一些 消息 應該怎么處理呢, 所以 我們 傳給 Service 進程的消息 要 帶上 replyTo 這個值, replyTo 是一個 處理 Service 進程數(shù)據(jù)返回的 Messenger.


3. 創(chuàng)建 用于 處理 service 進程返回 數(shù)據(jù)的 Messenger,說白了就是 創(chuàng)建 一個 可以暴漏給 Service 進程 調(diào)用的 遠程 binder 對象,



二. 再講一下原理:


? ? 概述:?

? ? ? ? ? ? 在 Service 端 創(chuàng)建 一個 Messenger 對象, 構造函數(shù)的入?yún)?Handler, 則 在 當前進程 中 創(chuàng)建一個 IMessenger.Stub 對應的 子類 MessengerImpl 的 Binder 對象, 這個 Binder 為 本地Binder. 在 Service 中的 onBinder() 回調(diào)方法中 調(diào)用 Messenger 對象的 getBinder() 進行返回( 實際上調(diào)用的是 MessengerImpl.asBinder() 方法),?

? ? ? ? ? ? 在 Client 端中的 ServiceConnection 接口的實現(xiàn)類 中的 onServiceConnected() 方法的第二個參數(shù) 為 Service 返回的 代理 Binder, 則 使用 Messenger 構造函數(shù) 中 入?yún)?IBinder 的 創(chuàng)建一個 Messenger 對象, ?在 Client 端 創(chuàng)建的 這個 Messenger 是 用來 向 ?Service 端 發(fā)送 Messager 消息的, Messager 消息 對應的 處理 邏輯 是在 Service 端 的 Messenger 對象中的 handleMessage(){} 方法中實現(xiàn)的.

? ? ? ? ? ? 在前面只講到了 從 Client 端發(fā)送 Message 消息 給 Service 端, 但如果 想 通過 Service 端返回 消息 給 Client 端呢, 則 在 Client 端 創(chuàng)建一個 構造函數(shù)入?yún)?為 Handler 的 Messenger 對象 delReturn , 然后 將 Client端發(fā)給 Service 端 對應的 Message 的 ?replyTo 字段 賦值為 delReturn 指向的對象, 則 Service 端就可以 通過 Message.replyTo 對應的 Messenger 向 Client端發(fā)送 Message.


? ? ? ? ? ? 小結一下 : ?通過 Messenger 來 實現(xiàn) 進程間通信的 好處是:

? ? ? ? ? ? ? ? ? ? ? ? 1. 不用煩惱 前后臺 約定的 進程間通信協(xié)議的變換(aidl文件) , ?因為 Messenger 機制里 可以通過 修改 handleMessage() 的實現(xiàn)就可以了,不用修改 遠程調(diào)用 接口

? ? ? ? ? ? ? ? ? ? ? ? 2. ?避免客戶端調(diào)用 Service 遠程 方法 的線程會被阻塞. ?, Binder機制中 Client端 調(diào)用 Service 端 時, Client端對應的線程會等到 Service 端 線程返回才開始繼續(xù)執(zhí)行,, 由于 Messenger 在 ipc 通信上 借鑒了 Handler 機制,因此 可以把 方法執(zhí)行 和方法返回分開 , Messenger 機制下的 client 端 對應的線程 無需 等待 消息 執(zhí)行完成.


-------------------------------------------------------------------------------------------------------------------------------------------------

? ? ? ? 1. ?首先, 我們看到 IMessenger 對應的 aidl 文件: 可以知道 IMessenger 對應的是 一個 有 send(Message msg) 方法的Binder 對象.


? ? ? ? 2. 在 Handler.MessengerImpl ?類 中 我們可以看到 IMessenger.Stub 本地 binder 端 的代碼實現(xiàn)為 : 通過 Handler 的 sendMessage() 方法把 獲取到的Message 消息 發(fā)給對應的線程的looper中.


? ? ? ? 3. 在 上面代碼截圖中, 我們可以看到 Handler 中 有一個 方法 getIMessenger(), 其作用是 返回一個 MessengerImpl() 對象實例. 在使用的時候 我們會 創(chuàng)建 Messenger 對象, 則 從 Messenger 的構造函數(shù)中 我們可以看到:


? ? ? ? --> Messenger 有 兩個構造函數(shù), 其中 一個 入?yún)?為 Handler對象, 則 mTarget 對應的 是 IMessenger ?aidl 接口 對應的 實體類.


? ? ? ? --> ?下面是 入?yún)?為 IBinder 對象, 則 target 為 IMessenger aidl 接口 對應的 代理類, 用來 把 消息 Messenger 從當前 進程 發(fā)到 IMessenger 對應的 實體類 所在的進程 進行處理:


最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,572評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,071評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,409評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,569評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,360評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,895評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,979評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,123評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,643評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,559評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,742評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,250評論 5 356
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 43,981評論 3 346
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,363評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,622評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,354評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,707評論 2 370

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