Android的跨进程通信
Android系統(tǒng)的跨進(jìn)程簡(jiǎn)介
為什么不能直接跨進(jìn)程通信?
為了安全考慮,應(yīng)用之間的內(nèi)存是無法互相訪問的,各自的數(shù)據(jù)都存在于自身的內(nèi)存區(qū)域內(nèi)。
如何跨進(jìn)程通信?
要想跨進(jìn)程通信,就要找到一個(gè)大家都能訪問的地方,例如硬盤上的文件,多個(gè)進(jìn)程都可以讀寫該文件,通過對(duì)該文件進(jìn)行讀寫約定好的數(shù)據(jù),來達(dá)到通信的目的。
Android中的跨進(jìn)程通信采用的是Binder機(jī)制,其底層原理是共享內(nèi)存。
Binder機(jī)制
- Android中的跨進(jìn)程通信采用的是Binder機(jī)制。
- Binder在linux層面屬于一個(gè)驅(qū)動(dòng),但是這個(gè)驅(qū)動(dòng)不是去驅(qū)動(dòng)一個(gè)硬件,而且驅(qū)動(dòng)一小段內(nèi)存。
- 不同的應(yīng)用通過對(duì)一塊內(nèi)存區(qū)域進(jìn)行數(shù)據(jù)的讀、寫操作來達(dá)到通信的目的。
- 不同的應(yīng)用在同一內(nèi)存區(qū)域讀寫數(shù)據(jù),為了告知其他應(yīng)用如何理解寫入的數(shù)據(jù),就需要一個(gè)說明文件,這就是AIDL。當(dāng)兩個(gè)應(yīng)用持有相同的AIDL文件,就能互相理解對(duì)方的的意圖,就能做出相應(yīng)的回應(yīng),達(dá)到通信的目的。
系統(tǒng)服務(wù)
什么是系統(tǒng)服務(wù)?
由android系統(tǒng)提供的服務(wù),以供應(yīng)用程序調(diào)用,來操作手機(jī)。如果應(yīng)用能直接操作手機(jī),后果將不堪設(shè)想,為了安全性和統(tǒng)一性,所有手機(jī)操作都將由系統(tǒng)來完成,應(yīng)用通過發(fā)送消息給系統(tǒng)服務(wù)來請(qǐng)求操作。系統(tǒng)服務(wù)就是系統(tǒng)開放給應(yīng)用端的操作接口,類似于Web服務(wù)開放出來的接口。
我們通過context. getSystemService可以獲取到系統(tǒng)服務(wù)的代理對(duì)象,該代理對(duì)象內(nèi)部有一個(gè)系統(tǒng)服務(wù)的遠(yuǎn)程對(duì)象引用。代理對(duì)象和系統(tǒng)服務(wù)有相同的api接口,我們調(diào)用代理對(duì)象,代理對(duì)象會(huì)調(diào)用遠(yuǎn)程對(duì)象,遠(yuǎn)程對(duì)象通知系統(tǒng)服務(wù),這樣操作起來就像直接訪問系統(tǒng)服務(wù)一樣輕松。
系統(tǒng)服務(wù)和應(yīng)用端的通信機(jī)制
- 系統(tǒng)服務(wù)XxxService
是一個(gè)Binder類的子類,一旦創(chuàng)建后,就開啟一個(gè)線程死循環(huán)用來檢測(cè)某段內(nèi)存是否有數(shù)據(jù)寫入
- Binder驅(qū)動(dòng)
自身創(chuàng)建時(shí),創(chuàng)建一個(gè)XxxRemote遠(yuǎn)程對(duì)象,存放到Binder驅(qū)動(dòng)中,XxxRemote遠(yuǎn)程對(duì)象可以和XxxService系統(tǒng)服務(wù)通信
- 應(yīng)用端
通過context. getSystemService()獲取XxxServiceProxy對(duì)象,該對(duì)象內(nèi)部引用了XxxRemote對(duì)象, XxxServiceProxy和XxxService具有相同的API,我們調(diào)用XxxServiceProxy時(shí),XxxServiceProxy就調(diào)用XxxRemote并等待XxxRemote返回。XxxRemote會(huì)往某段內(nèi)存中寫入數(shù)據(jù),寫完后就開始監(jiān)視該內(nèi)存區(qū)域,Binder驅(qū)動(dòng)會(huì)把XxxRemote寫入的數(shù)據(jù)拷貝到XxxService監(jiān)視著的內(nèi)存區(qū)域,當(dāng)XxxService一旦發(fā)現(xiàn)有數(shù)據(jù),就讀取并進(jìn)行處理,處理完畢后,就寫入該區(qū)域,這是Binder驅(qū)動(dòng)又會(huì)把該數(shù)據(jù)拷貝到XxxRemote監(jiān)視的內(nèi)存區(qū)域,當(dāng)XxxService發(fā)現(xiàn)內(nèi)存區(qū)域有數(shù)據(jù)讀取該區(qū)域數(shù)據(jù),并把內(nèi)容返回給XxxServiceProxy。這樣就完成了一次進(jìn)程間的通信。
所以一個(gè)系統(tǒng)服務(wù)會(huì)產(chǎn)生兩個(gè)Binder對(duì)象,一個(gè)是運(yùn)行在系統(tǒng)中的系統(tǒng)服務(wù)本身,一個(gè)是存放到Binder驅(qū)動(dòng)中的遠(yuǎn)程對(duì)象。所不同的是系統(tǒng)服務(wù)Binder對(duì)象對(duì)開啟一個(gè)線程監(jiān)聽消息,遠(yuǎn)程對(duì)象不會(huì),它是運(yùn)行在調(diào)用者的線程中。
客戶端也可以不使用系統(tǒng)服務(wù)的遠(yuǎn)程Binder對(duì)象,而是自己創(chuàng)建一個(gè)Binder對(duì)象,通過Binder驅(qū)動(dòng)和系統(tǒng)服務(wù)進(jìn)行關(guān)聯(lián),這樣的好處客戶端可以隨時(shí)通知系統(tǒng)服務(wù),系統(tǒng)服務(wù)也可以隨時(shí)通知客戶端,而不是像上面所說的系統(tǒng)服務(wù)只能被動(dòng)的等著客戶端調(diào)用。
Binder間的通信機(jī)制
Binder對(duì)象都有各自的內(nèi)存區(qū)域,當(dāng)Binder1想要向Binder2發(fā)送數(shù)據(jù)時(shí),就會(huì)把數(shù)據(jù)寫入自己的內(nèi)存區(qū)域,然后通知Binder驅(qū)動(dòng),Binder驅(qū)動(dòng)會(huì)把數(shù)據(jù)拷貝到Binder2的內(nèi)存區(qū)域,然后通知Binder2進(jìn)行讀取,Binder讀取完畢后,將把數(shù)據(jù)寫入binder2的內(nèi)存區(qū)域,然后通知Binder驅(qū)動(dòng),Binder驅(qū)動(dòng)將會(huì)把數(shù)據(jù)拷貝到Binder1的內(nèi)存區(qū)域中。這樣就完成了一次通信。
如果Binder1是系統(tǒng)服務(wù),Binder2是系統(tǒng)服務(wù)的遠(yuǎn)程對(duì)象,這樣任何應(yīng)用程序在獲取了Binder2的引用后,都可以和Binder1進(jìn)行通信。但是缺點(diǎn)也很明顯,只能由應(yīng)用端請(qǐng)求系統(tǒng)服務(wù),系統(tǒng)服務(wù)不能主動(dòng)去聯(lián)系應(yīng)用端。WifiManagerService之類的就是采用這種方式。
還有一種方式是Binder1是系統(tǒng)服務(wù),Binder2是應(yīng)用端創(chuàng)建的Binder對(duì)象,他們兩者通過Binder驅(qū)動(dòng)進(jìn)行連接后,應(yīng)用端可以主動(dòng)調(diào)系統(tǒng)服務(wù),系統(tǒng)服務(wù)也可以主動(dòng)調(diào)用應(yīng)用端。WindowManagerService就是采用的這種方式。
IPC
進(jìn)程間通信或跨進(jìn)程通信,是指兩個(gè)進(jìn)程間進(jìn)行數(shù)據(jù)交換的過程。
PRC:遠(yuǎn)程過程調(diào)用
多進(jìn)程
線程是CPU調(diào)度的最小單元,同時(shí)線程是一種有限的系統(tǒng)資源。而進(jìn)程一般指一個(gè)執(zhí)行單元,在PC和移動(dòng)設(shè)備上指一個(gè)程序或者一個(gè)應(yīng)用。一個(gè)進(jìn)程可以包含多個(gè)線程,因此進(jìn)程和線程是包含與被包含的關(guān)系。
- Intent
- Bundle
- 共享文件
- SharedPrefrence
- ContentProvider
- Messenger
- AIDL
- Binder
- Socket
Android中的多進(jìn)程模式
- 一個(gè)應(yīng)用中存在多個(gè)進(jìn)程的情況
- 多個(gè)應(yīng)用間的多進(jìn)程
序列化
序列化,反序列化,持久化
Serializable
Java提供的一個(gè)序列化接口
序列化流
- ObjectInputStream
- ObjectOutputStream
Parcelable
Android提供的序列化接口
Binder
實(shí)現(xiàn)IBinder接口,是Android的一種跨進(jìn)程通信方式,是客戶端和服務(wù)端進(jìn)行通信的媒介
- IBinder
- Binder
- Stub
當(dāng)客戶端發(fā)起遠(yuǎn)程請(qǐng)求時(shí),由于當(dāng)前線程會(huì)被掛起直至服務(wù)端進(jìn)程返回?cái)?shù)據(jù),所有一個(gè)遠(yuǎn)程方法是很耗時(shí)的,那么不能在UI線程中發(fā)起此遠(yuǎn)程請(qǐng)求;由于服務(wù)端的Binder運(yùn)行在Binder的線程池中,所以Binder方法不管是否耗時(shí)都采用同步的方式去實(shí)現(xiàn),因?yàn)樗呀?jīng)運(yùn)行在一個(gè)線程中了
Binder死亡代理
- linkToDeath()
- unlinkToDeath()
共享文件
一個(gè)進(jìn)程序列化對(duì)象到sd上的一個(gè)文件,另一個(gè)進(jìn)程反序列化sd上的一文件
Messenger
底層實(shí)現(xiàn)是AIDL,一次處理一個(gè)請(qǐng)求,不用考慮線程同步的問題,主要作用是傳遞消息
AIDL
- 只支持方法,不支持靜態(tài)常量
- AIDL的包結(jié)構(gòu)在服務(wù)端和客戶端要保持一致
RemoteCallbackList
- 實(shí)現(xiàn)了同步功能
總結(jié)
以上是生活随笔為你收集整理的Android的跨进程通信的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 实现圆形图片
- 下一篇: android sina oauth2.