国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 系統(tǒng) > Android > 正文

# 讀 Android 開(kāi)發(fā)藝術(shù)探索 &4

2019-11-09 17:57:42
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

關(guān)鍵詞:ipC 方式 / 共享文件 / ContentPRovider / Messenger / Intent + extras / Socket / Bundle

本次筆記梳理了所有可以進(jìn)行跨進(jìn)程通信的常見(jiàn)方式,包括使用 Bundle、使用文件共享、使用 Messenger、使用 AIDL、使用 ContentProvider、使用 Socket。

1. 使用 Bundle #

是一種最簡(jiǎn)單的進(jìn)程間通信;用來(lái)直接傳遞數(shù)據(jù),在 Bundle 中附加我們需要傳輸給遠(yuǎn)程進(jìn)程的信息并通過(guò) Intent 發(fā)送出去,我們傳輸?shù)臄?shù)據(jù)也應(yīng)該被序列化;四大組件中的 Activity / Service / Receiver 都支持在 Intent 中傳遞 Bundle 數(shù)據(jù);Bundle 實(shí)現(xiàn)了 Parcelable 接口,可以方便地在不同進(jìn)程間傳輸;A 進(jìn)程在進(jìn)行一個(gè)計(jì)算,計(jì)算完成之后要啟動(dòng) B 進(jìn)程中的一個(gè)組件并把計(jì)算結(jié)果傳遞給 B 進(jìn)程,但是這個(gè)計(jì)算結(jié)果不支持寫入 Bundle 中,無(wú)法通過(guò) Intent 來(lái)傳輸怎么辦? 最簡(jiǎn)單方案:將需要在 A 中計(jì)算的任務(wù)轉(zhuǎn)移到 B 進(jìn)程的后臺(tái) Service 中去執(zhí)行,這樣不斷避免了進(jìn)程間通信的問(wèn)題,還只用了很小的代價(jià)。

2. 使用文件共享 #

兩個(gè)進(jìn)程通過(guò)讀 / 寫同一個(gè)文件來(lái)交換數(shù)據(jù),A 把數(shù)據(jù)寫入文件,B 通過(guò)讀取這個(gè)文件來(lái)獲取數(shù)據(jù);Android 系統(tǒng)基于 linux,使得其并發(fā)讀 / 寫文件可以沒(méi)有限制的進(jìn)行,甚至兩個(gè)線程同時(shí)對(duì)同一個(gè)文件進(jìn)行寫操作都可以,盡管會(huì)出現(xiàn)問(wèn)題;可以序列化一個(gè)對(duì)象到文件系統(tǒng)中的同時(shí)從另一個(gè)進(jìn)程中恢復(fù)這個(gè)對(duì)象;文件共享方式適合在對(duì)數(shù)據(jù)同步要求不高的進(jìn)程之間進(jìn)行通信,并且妥善處理并發(fā)讀寫的問(wèn)題;不建議在進(jìn)程間通信中使用 SharedPreferences,SharedPreferences 是 Android 中提供的輕量級(jí)存儲(chǔ)方案,通過(guò)鍵值對(duì)的方式來(lái)存儲(chǔ)數(shù)據(jù),在底層上采用 xml 文件來(lái)存儲(chǔ)鍵值對(duì),目錄位于 /data/data/package_name/shared_prefs 目錄下,屬于文件的一種,在多線程模式下,面對(duì)高并發(fā)的讀 / 寫訪問(wèn)會(huì)丟失數(shù)據(jù),因?yàn)橛芯彺娌呗裕x寫變得不可靠;

3. 使用 Messenger #

是一種輕量級(jí)的 IPC 方案,底層實(shí)現(xiàn)是 AIDL;可以在不同的進(jìn)程中傳遞 Message 對(duì)象,信使;對(duì) AIDL 進(jìn)行了封裝一次只處理一個(gè)請(qǐng)求,在服務(wù)端不用考慮線程同步的問(wèn)題,服務(wù)端不存在并發(fā)執(zhí)行的情形;在 Messenger 中進(jìn)行數(shù)據(jù)傳遞必須將數(shù)據(jù)放到 Message 中,而 Messenger 和 Message 實(shí)現(xiàn)了 Parcelable 接口,因此可以跨進(jìn)程傳輸;Message 中能能使用的載體只有 what、arg1、arg2、Bundle 以及 replyTo;Messenger 以串行的方式處理客戶端發(fā)來(lái)的消息;服務(wù)端一個(gè)一個(gè)的處理,不適合大量的并發(fā)請(qǐng)求;實(shí)際上作用主要是為了傳遞消息,不適合跨進(jìn)程調(diào)用服務(wù)端的方法(這時(shí)候需要考慮使用 AIDL)

Messenger 工作原理

4. 使用 AIDL #

服務(wù)端 首先創(chuàng)建一個(gè) Service 用來(lái)監(jiān)聽(tīng)客戶端的連接請(qǐng)求,然后創(chuàng)建一個(gè) AIDL 文件,將暴露給客戶端的接口在這個(gè) AIDL 文件中聲明,最后在 Service 中實(shí)現(xiàn)這個(gè) AIDL 接口即可;客戶端 首先綁定服務(wù)端的 Service,綁定成功之后,將服務(wù)端返回的 Binder 對(duì)象轉(zhuǎn)成 AIDL 接口所屬的類型,接著就可以調(diào)用 AIDL 中的方法了;AIDL 接口的創(chuàng)建 創(chuàng)建一個(gè) .aidl 文件,里面聲明一個(gè)接口與若干個(gè)接口方法,AIDL 的接口只支持方法,不支持聲明靜態(tài)變量,有別于傳統(tǒng)的接口遠(yuǎn)程服務(wù)端 Service 的實(shí)現(xiàn) 實(shí)現(xiàn) AIDL 的接口,首先要?jiǎng)?chuàng)建一個(gè) Service,創(chuàng)建一個(gè) Binder 對(duì)象,并在 onBinder 中返回它。AIDL 方法是在服務(wù)端的 Binder 線程池中執(zhí)行的,在 AIDL 方法中處理線程同步;客戶端的實(shí)現(xiàn) 首先綁定遠(yuǎn)程服務(wù),綁定成功之后將服務(wù)端返回的 Binder 對(duì)象轉(zhuǎn)換成 AIDL 接口,然后就可以通過(guò)這個(gè)接口去調(diào)用服務(wù)端的遠(yuǎn)程方法了;(AIDL 中無(wú)法使用普通接口)

[ 還有幾點(diǎn)需要知道 ]

對(duì)象是不能跨進(jìn)程直接傳輸?shù)模瑢?duì)象的跨進(jìn)程傳輸本質(zhì)上都是反序列化的過(guò)程,這就是為什么 AIDL 中自定義對(duì)象都必須要實(shí)現(xiàn) Parcelable 接口的原因;雖然說(shuō)多次跨進(jìn)程傳輸客戶端的同一個(gè)對(duì)象會(huì)在服務(wù)端生成不同的對(duì)象,但是這些新生成的對(duì)象有一個(gè)共同點(diǎn),那就是它們底層的 Binder 對(duì)象是同一個(gè);客戶端調(diào)用遠(yuǎn)程服務(wù)的方法,被調(diào)用的方法運(yùn)行在服務(wù)端的 Binder 線程池中,同時(shí)客戶端線程會(huì)被掛起,服務(wù)器端方法不能執(zhí)行耗時(shí)的方法(如果是客戶端是 UI 線程的話),防止 ANR;客戶端的 onServiceConnected 和 onServiceDisconnected 方法都運(yùn)行在 UI 線程中,所以也不可以在它們里面直接調(diào)用服務(wù)端的耗時(shí)方法;

5. 使用 ContentProvider #

專門用于不同應(yīng)用之間進(jìn)行數(shù)據(jù)共享的方式,天生適合進(jìn)程間通信;和 Messenger 一樣,ContentProvider 的底層實(shí)現(xiàn)同樣也是 Binder,由此可見(jiàn),Binder 在 Android 系統(tǒng)中很重要;系統(tǒng)封裝,無(wú)需關(guān)心底層細(xì)節(jié)即可輕松實(shí)現(xiàn) IPC;系統(tǒng)內(nèi)置了很多 ContentProvider 比如通信錄信息、日程表信息等,跨進(jìn)程訪問(wèn)只需要通過(guò) ContentResolver 的 query、update、insert 和 delete 方法即可;六個(gè)抽象方法:onCreate / query / update / insert / delete / getType ;ContentProvider 主要以表格的形式來(lái)組織數(shù)據(jù);也支持文件數(shù)據(jù)比如,圖片、視頻等;系統(tǒng)提供的 MediaStore 功能就是文件類型的 ContentProvider;query / update / insert / delete 四大方法存在多線程并發(fā)訪問(wèn),此方法內(nèi)要做好線程同步;ContentProvider 支持自定義調(diào)用,通過(guò) ContentProvider 的 Call 方法和 ContentResolver 的 Call 方法;

6. 使用 Socket #

Socket 被稱為 “套接字” ,分為 流式套接字用戶數(shù)據(jù)報(bào)套接字;流式套接字對(duì)應(yīng)著網(wǎng)絡(luò)中傳輸控制層的 TCP 協(xié)議;用戶數(shù)據(jù)報(bào)套接字對(duì)應(yīng)著網(wǎng)絡(luò)中傳輸控制層的 UDP 協(xié)議;Socket 本身可以支持傳輸任意字節(jié)流,實(shí)現(xiàn)信息的傳輸,是一種 IPC 方式;實(shí)際上,通過(guò) Socket 不僅僅能實(shí)現(xiàn)進(jìn)程間的通信,還可以實(shí)現(xiàn)設(shè)備之間的通信(前提是這些設(shè)備之間的 IP 地址相互可見(jiàn));

7. IPC 各方式的優(yōu)缺點(diǎn)和適用場(chǎng)景

/ 名稱 / / 優(yōu)點(diǎn) / / 缺點(diǎn) / / 適用場(chǎng)景 /
/ Bundle / / 簡(jiǎn)單易用 / / 只能支持 Bundle 支持的數(shù)據(jù)類型 / / 四大組件之間的進(jìn)程間通信 /
/ 文件共享 / / 簡(jiǎn)單易用 / / 不適合高并發(fā)場(chǎng)景,并且無(wú)法做到進(jìn)程間的即時(shí)通信 / / 無(wú)并發(fā)訪問(wèn)情形,交換簡(jiǎn)單的數(shù)據(jù),實(shí)時(shí)性不高的場(chǎng)景 /
/ AIDL / / 功能強(qiáng)大,支持一對(duì)多并發(fā)通信,支持實(shí)時(shí)通信 / / 使用稍復(fù)雜,需要處理好線程同步 / 一對(duì)多通信且有 RPC 需求 /
/ Messenger / / 功能一般,支持一對(duì)多串行通信,支持實(shí)時(shí)通信 / / 不能很好地處理高并發(fā)情形,不支持 RPC,數(shù)據(jù)通過(guò) Message 進(jìn)行傳輸,因此只能傳輸 Bundle 支持的數(shù)據(jù)類型 / / 低并發(fā)的一對(duì)多即時(shí)通信,無(wú) RPC 需求,或者無(wú)要返回結(jié)果的 RPC 需求 /
/ ContentProvider / / 在數(shù)據(jù)源訪問(wèn)方面功能強(qiáng)大,支持一對(duì)多并發(fā)數(shù)據(jù)共享,可通過(guò) Call 方法擴(kuò)展其他操作 / / 可以理解為受約束的 AIDL,主要提供數(shù)據(jù)源的 CRUD 操作 / 一對(duì)多的進(jìn)程間的數(shù)據(jù)共享
/ Socket / / 功能強(qiáng)大,可以通過(guò)網(wǎng)絡(luò)傳輸字節(jié)流,支持一對(duì)多并發(fā)實(shí)時(shí)通信 / / 實(shí)現(xiàn)細(xì)節(jié)稍微有點(diǎn)繁瑣,不支持直接的 RPC / / 網(wǎng)絡(luò)數(shù)據(jù)交換 /

End.

Note by HF. Learn from 《Android 開(kāi)發(fā)藝術(shù)探索》



發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 张家港市| 青河县| 澎湖县| 灵石县| 平和县| 出国| 龙陵县| 龙里县| 特克斯县| 柘城县| 综艺| 湾仔区| 玉林市| 萨迦县| 红原县| 拉孜县| 许昌县| 雷山县| 山丹县| 巴青县| 博兴县| 玉田县| 德令哈市| 灌阳县| 东阿县| 南皮县| 田林县| 瓦房店市| 都江堰市| 林甸县| 西宁市| 乾安县| 都江堰市| 安新县| 哈尔滨市| 腾冲县| 咸宁市| 靖西县| 宁远县| 荥阳市| 修武县|