Android: IPC 方式學(xué)習(xí)筆記

IPC 簡介


IPC 是 Inter-Process Communication 的縮寫琴锭,含義為進程間通信或跨進程通信氢哮,是指兩個進程之間進行數(shù)據(jù)交換的過程缓待。

IPC 的場景

  • 一個應(yīng)用由于自身需要编整,采用多進程方式實現(xiàn)缰儿。例如:某個模塊需要運行在單獨的進程中锦秒。
  • 兩個應(yīng)用交換數(shù)據(jù)露泊。

應(yīng)用使用多進程會導(dǎo)致的問題

  • 靜態(tài)成員和單例模式失效
    Android 為每個進程分配獨立的虛擬機,不同的虛擬機分配了不同的內(nèi)存空間旅择,一個進程中對靜態(tài)變量的修改只對本進程有效惭笑。
  • 線程同步機制失效
    不論鎖對象還是全局類都無法保證線程同步,因為在不同進程中鎖的不是同一個對象。
  • SharedPreferences 的可靠性降低
    兩個進程并發(fā)寫 SharedPreferences 沉噩,可能會發(fā)生數(shù)據(jù)丟失的情況捺宗。
  • Application 會多次創(chuàng)建
    每個進程運行在獨立的虛擬機上,會創(chuàng)建獨立的 Application 實例川蒙。

IPC 方式


1.Bundle

四大組件之三 Activity蚜厉、Service 和 BroadcastReceiver 均支持在 Intent 中傳遞 Bundle 數(shù)據(jù)。

當我們需要向其他進程傳輸數(shù)據(jù)時畜眨,可以通過 Intent 將需要傳遞的數(shù)據(jù)傳遞給目標進程的組件昼牛。

要求:需要傳遞的數(shù)據(jù)能夠被序列化,例如基本類型康聂、實現(xiàn)了 Parcelable 或 Serializable 接口的類的實例贰健、Android 支持的特殊對象。

Bundle 不支持的類型無法通過這種方式進行進程間通信早抠。

2. 文件共享

兩個進程通過讀寫同一個文件來交換數(shù)據(jù)霎烙。

除了可以交換文本信息外撬讽,也可以傳遞序列化的對象蕊连。

適用場景:對數(shù)據(jù)同步要求不高的進程間通信,需要妥善處理并發(fā)讀寫問題游昼。

SharedPreferences 是使用 XML 文件來存儲鍵值對的甘苍,但是 Android 系統(tǒng)會在內(nèi)存中對它進行緩存,在多進程模式下烘豌,系統(tǒng)對它的讀寫就不再可靠载庭。當面對高并發(fā)的讀寫訪問時,SharedPreferences 很可能會丟失數(shù)據(jù)廊佩。所以囚聚,不建議在進程間通信中使用 SharedPreferences,可以考慮使用 MMKV标锄。

MMKV for Android 多進程訪問支持的設(shè)計與實現(xiàn)

3. Messenger

Messenger 信使顽铸,它可以在不同進程間傳遞 Message 對象。在 Message 對象中放入需要傳遞的數(shù)據(jù)料皇,就可以輕松地實現(xiàn)進程間傳遞數(shù)據(jù)的目標谓松。

Messenger 是一種輕量級的 IPC 方案,底層實現(xiàn)是 AIDL 践剂。

Message 中能使用的載體有 what(int)鬼譬、arg1(int)、arg2(int)逊脯、Bundle 和 replyTo(Messenger) 优质。

Messenger 的使用
  1. 服務(wù)端進程
  • 創(chuàng)建一個 Service 來處理客戶端的連接請求
  • 創(chuàng)建一個 Handler,并通過它來創(chuàng)建一個 Messenger 對象
  • 在 Service 的 onBind 中返回 Messenger 對象底層的 IBinder
  1. 客戶端進程
  • 綁定服務(wù)端的 Service,用服務(wù)端返回的 IBinder 對象創(chuàng)建一個 Messenger
  • 用 Messenger 向服務(wù)端發(fā)送消息盆赤,消息的類型為 Message

通過以上操作贾富,就可以完成客戶端向服務(wù)端的單向通信了。如需支持服務(wù)端響應(yīng)客戶端:

  1. 客戶端進程
  • 創(chuàng)建一個 Handler牺六,并通過它創(chuàng)建一個新的 Messenger 對象
  • 將新創(chuàng)建的 Messenger 對象通過 Message 的 replyTo 參數(shù)傳遞給服務(wù)端進程
  1. 服務(wù)端進程
  • 取出客戶端通過 replyTo 參數(shù)的傳遞過來的 Messenger 對象
  • 使用 Messenger 對象回應(yīng)客戶端
Messenger的工作原理.png

4. AIDL

使用 AIDL 進行進程間通信的流程
  1. 服務(wù)端
  • 創(chuàng)建一個 Service颤枪,用來監(jiān)聽客戶端的連接請求
  • 創(chuàng)建一個 AIDL 文件,用來聲明暴露給客戶端的接口
  • 在 Service 中實現(xiàn) AIDL 文件中聲明的接口
  1. 客戶端
  • 綁定服務(wù)端的 Service
  • 將服務(wù)端返回的 Binder 對象轉(zhuǎn)成 AIDL 接口所屬的類型
  • 調(diào)用 AIDL 中的方法

AIDL 支持的數(shù)據(jù)類型

  • 基本數(shù)據(jù)類型
  • String 和 CharSequence
  • ArrayList淑际,集合中的每個元素必須被 AIDL 支持
  • HashMap畏纲,集合中的每個元素必須被 AIDL 支持,包括 key 和 value
  • Parcelable:所有實現(xiàn)了 Parcelable 接口的類
  • AIDL:所有的 AIDL 接口

5. ContentProvider

ContentProvider 是 Android 提供的不同應(yīng)用間數(shù)據(jù)共享的方式春缕,底層實現(xiàn)是 Binder盗胀。

Android 系統(tǒng)預(yù)置了許多 ContentProvider,比如通訊錄信息锄贼、日程表信息等票灰,要跨進程訪問這些信息,只需要通過 ContentResolver 的 query()宅荤、update()屑迂、insert() 和 delete() 方法即可。

ContentProvider 主要以表格的形式組織數(shù)據(jù)冯键,和數(shù)據(jù)庫相似惹盼。它還支持文件文件數(shù)據(jù),例如圖片惫确、視頻等手报。Android 提供的 MediaStore 就是文件類型的 ContentProvider。

雖然 ContentProvider 的底層數(shù)據(jù)看起來很像一個 SQLite 數(shù)據(jù)庫改化,但是它對數(shù)據(jù)的存儲方法并沒有任何要求掩蛤,我們既可以使用 SQLite 數(shù)據(jù)庫,也可以使用普通的文件陈肛,甚至可以采用內(nèi)存中的一個對象來進行數(shù)據(jù)的存儲揍鸟。

自定義 ContentProvider
  • 繼承 ContentProvider 類,實現(xiàn) 6 個抽象方法:onCreate()燥爷、query()蜈亩、update()、insert()前翎、delete() 和 getType() 稚配。
  • 建立數(shù)據(jù)存儲系統(tǒng),比較常用的使用 SQLite 數(shù)據(jù)庫港华。
  • 注冊 ContentProvider道川,在 AndroidManifest 文件中聲明。
ContentProvider 的抽象方法
  • onCreate() : ContentProvider 的初始化。
  • getType() : 返回一個 Uri 請求所對應(yīng)的 MIME 類型冒萄。
  • query()臊岸、update()、insert() 和 delete(): 數(shù)據(jù)的增刪改查尊流。
  • 6 個方法均運行在 ContentProvider 的進程中帅戒,onCreate() 由系統(tǒng)回調(diào)并運行在主線程里,其他 5 個方法均由外界回調(diào)并運行在 Binder 線程池中崖技。

6. Socket

Socket逻住,套接字,是網(wǎng)絡(luò)通信中的概念迎献。分為流式套接字和用戶數(shù)據(jù)報套接字兩種瞎访,分別對應(yīng)網(wǎng)絡(luò)的傳輸控制層中的 TCP 和 UDP。

通過 Socket 不僅能實現(xiàn)進程間的通信吁恍,還可以實現(xiàn)設(shè)備間的通信扒秸,前提是通信的設(shè)備的 IP 地址互相可見。

IPC 方式比較

名稱 優(yōu)點 缺點 適用場景
Bundle 簡單易用 只能傳輸 Bundle 支持的數(shù)據(jù)類型 四大組件間的進程間通信
文件共享 簡單易用 不適合高并發(fā)場景冀瓦,不支持進程間的即時通信 無并發(fā)需求伴奥,交換簡單的數(shù)據(jù),對實時性要求不高
AIDL 支持一對多并發(fā)通信咕幻,支持實時通信 使用比較復(fù)雜渔伯,需要處理好線程同步 一對多通信顶霞,有 RPC 需求
Messenger 支持一對多串行通信肄程,支持實時通信 只能傳輸 Bundle 支持的數(shù)據(jù)類型,不能很好地處理高并發(fā)情形选浑,不支持 RPC 低并發(fā)的一對多通信蓝厌,無 RPC 需求,或者有不需要返回結(jié)果的 RPC 需求
ContentProvider 支持一對多并發(fā)數(shù)據(jù)共享古徒,可通過 Call 方法擴展其他操作 主要提供數(shù)據(jù)源的 CRUD 操作 一對多的進程間的數(shù)據(jù)共享
Socket 支持一對多并發(fā)實時通信拓提,可以通過網(wǎng)絡(luò)傳輸字節(jié)流 使用比較復(fù)雜,不支持直接 RPC 網(wǎng)絡(luò)數(shù)據(jù)交換

測試設(shè)備參數(shù)

  • 型號:vivo Y66L
  • 操作系統(tǒng):Funtouch OS 3.0(Android 6.0.1)

參考資料

任玉剛.Android 開發(fā)藝術(shù)探索[M].電子工業(yè)出版社:北京,2015:35-121.

示例代碼

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末隧膘,一起剝皮案震驚了整個濱河市代态,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌疹吃,老刑警劉巖蹦疑,帶你破解...
    沈念sama閱讀 219,110評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異萨驶,居然都是意外死亡歉摧,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來叁温,“玉大人再悼,你說我怎么就攤上這事∠サ” “怎么了冲九?”我有些...
    開封第一講書人閱讀 165,474評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長跟束。 經(jīng)常有香客問我娘侍,道長,這世上最難降的妖魔是什么泳炉? 我笑而不...
    開封第一講書人閱讀 58,881評論 1 295
  • 正文 為了忘掉前任憾筏,我火速辦了婚禮,結(jié)果婚禮上花鹅,老公的妹妹穿的比我還像新娘氧腰。我一直安慰自己,他們只是感情好刨肃,可當我...
    茶點故事閱讀 67,902評論 6 392
  • 文/花漫 我一把揭開白布古拴。 她就那樣靜靜地躺著,像睡著了一般真友。 火紅的嫁衣襯著肌膚如雪黄痪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,698評論 1 305
  • 那天盔然,我揣著相機與錄音桅打,去河邊找鬼。 笑死愈案,一個胖子當著我的面吹牛挺尾,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播站绪,決...
    沈念sama閱讀 40,418評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼遭铺,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了恢准?” 一聲冷哼從身側(cè)響起魂挂,我...
    開封第一講書人閱讀 39,332評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎馁筐,沒想到半個月后涂召,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,796評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡眯漩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,968評論 3 337
  • 正文 我和宋清朗相戀三年芹扭,在試婚紗的時候發(fā)現(xiàn)自己被綠了麻顶。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,110評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡舱卡,死狀恐怖辅肾,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情轮锥,我是刑警寧澤矫钓,帶...
    沈念sama閱讀 35,792評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站舍杜,受9級特大地震影響新娜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜既绩,卻給世界環(huán)境...
    茶點故事閱讀 41,455評論 3 331
  • 文/蒙蒙 一概龄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧饲握,春花似錦私杜、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至笆怠,卻和暖如春铝耻,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蹬刷。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評論 1 272
  • 我被黑心中介騙來泰國打工瓢捉, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人箍铭。 一個月前我還...
    沈念sama閱讀 48,348評論 3 373
  • 正文 我出身青樓泊柬,卻偏偏與公主長得像椎镣,于是被迫代替她去往敵國和親诈火。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,047評論 2 355

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