2.1 Android IPC 簡介
IPC是 Inter-Process Conmmunication的縮寫猜欺,含義為進(jìn)程間通信或者跨進(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)系讳嘱。
通過給四大組件指定android:process屬性幔嗦,可以開啟多進(jìn)程模式
android:process=“:remote"
進(jìn)程名以“:”開頭的進(jìn)程屬于當(dāng)前應(yīng)用的私有進(jìn)程,其他應(yīng)用的組件不能和他跑在同一個(gè)進(jìn)程中
android:process=“com.didi"
而進(jìn)程名不以“:”開頭的屬于全局進(jìn)程沥潭,其他應(yīng)用可以通過ShareUID方式和他跑在同一個(gè)進(jìn)程中
一般情況下邀泉,使用多進(jìn)程會(huì)造成如下幾個(gè)方面問題
(1)靜態(tài)成員和單例模式完全失效
(2)線程同步機(jī)制完全失效
(3)SharePreference 的可靠性下降
(4)Application會(huì)多次創(chuàng)建
2.3 IPC基礎(chǔ)概念介紹
2.3.1 Serializable接口
Serializable為java所提供的一個(gè)序列化接口。想讓一個(gè)對象序列化钝鸽,只需要這個(gè)類實(shí)現(xiàn)Serializable接口并聲明一個(gè)serialVersionUID即可
2.3.2 Parcelable接口
2.3.3 Binder
Binder是android中的一個(gè)類汇恤,它集成了Binder接口。從IPC角度來說拔恰,Binder是Android中的一種跨進(jìn)程通信方式因谎。從Android Framework的角度來說,Binder是ServiceManager連接各種8uManager(Activitymanager,Windowmanager等)和相應(yīng)ManagerService的橋梁颜懊。從Android應(yīng)用層來說财岔,Binder是客戶端和服務(wù)端進(jìn)行通信的媒介,當(dāng)bindservice的時(shí)候河爹,服務(wù)端會(huì)返回一個(gè)包含了服務(wù)端業(yè)務(wù)調(diào)用的Binder對象匠璧,通過這個(gè)binder對象,客戶端可以獲取服務(wù)端提供的服務(wù)或者數(shù)據(jù)咸这,這里的服務(wù)包括普通服務(wù)和基于AIDL的服務(wù)夷恍。
AIDL (android interface Definition Language)
IBookmanager接口核心是它的內(nèi)部類stub和stub的內(nèi)部代理類Proxy。
DESCRIPTOR
Binder的唯一標(biāo)識媳维,一般用當(dāng)前Binder的類名標(biāo)識酿雪。
asInterface(android.os.binder obj)
用于將服務(wù)端的binder對象轉(zhuǎn)換成客戶端所需的AIDL接口對象。這種轉(zhuǎn)換過程是區(qū)分進(jìn)程的侄刽,如果客戶端和服務(wù)端位于同一進(jìn)程执虹,那么此方法返回的就是服務(wù)端的Stub對象本身,否則返回的是系統(tǒng)封裝后的Stub.proxy對象唠梨。
asBinder
此方法返回當(dāng)前的Binder對象
onTransact
這份方法運(yùn)行在服務(wù)器的Binder線程池中,當(dāng)客戶端發(fā)起跨進(jìn)程請求時(shí)侥啤,請求會(huì)通過系統(tǒng)底層封裝過之后交由此方法來處理当叭。該方法的原型為public boolean onTransact(int code茬故,android.os.parcel data,android.os.parcel reply,int flags)
服務(wù)端通過code可以確定客戶端所請求的目標(biāo)方法是什么,接著從data中取出目標(biāo)方法所需的參數(shù)(如果目標(biāo)方法有參數(shù)的話)蚁鳖,然后執(zhí)行目標(biāo)方法磺芭。當(dāng)目標(biāo)方法執(zhí)行完畢后,就向reply中寫入返回值(如果目標(biāo)有返回值的話)onTransact方法的執(zhí)行過程就是這樣醉箕。需要注意的是钾腺,如果此方法返回false,那么客戶端的請求就會(huì)失敗讥裤。因此我們可以利用這個(gè)特性做權(quán)限驗(yàn)證放棒。
Proxy#getBookList
這個(gè)方法運(yùn)行在客戶端,當(dāng)客戶端遠(yuǎn)程調(diào)用此方法的時(shí)候己英,他的內(nèi)部實(shí)現(xiàn)是這樣的间螟,首先創(chuàng)建該方法所需要的輸入性Parcel對象_data,輸出型Parcel對象 _reply 和返回值對象List;然后把該方法的參數(shù)信息寫入_data(如果有參數(shù)的話);接著調(diào)用transact方法發(fā)起RPC(遠(yuǎn)程過程調(diào)用)請求损肛,同時(shí)當(dāng)前線程掛起厢破;然后服務(wù)端的OnTransact方法會(huì)被調(diào)用,直到RPC過程返回后治拿,當(dāng)前線程繼續(xù)執(zhí)行摩泪,并從_reply中取出RPC過程的返回?cái)?shù)據(jù);最后返回_reply中的數(shù)據(jù)
可以不寫AIDL類通過直接寫B(tài)inder類
2.4 Android中的IPC方式
2.4.1 使用Bundle
在Activity和Service劫谅,Receiver中支持Intent傳遞bundle數(shù)據(jù)
2.4.2使用文件共享
2.4.3 使用Messenger
Messenger是輕量級的IPC方案见坑,他的底層實(shí)現(xiàn)是AIDL
實(shí)現(xiàn)步驟:
1.服務(wù)端進(jìn)程 ,我們首先在服務(wù)端創(chuàng)建一個(gè)service來處理客戶端的連接請求同波,同時(shí)創(chuàng)建一個(gè)handler并通過它來創(chuàng)建一個(gè)Messenger對象鳄梅。然后在service中的onBind中返回這個(gè)Messenger對象底層的Binder即可
2.客戶端進(jìn)程,首先綁定服務(wù)端的service未檩,綁定成功后用服務(wù)端返回的Ibinder對象創(chuàng)建一個(gè)Messenger戴尸。通過這個(gè)Messenger就可以像服務(wù)端發(fā)送消息了,發(fā)送消息類型為Message對象冤狡。如果需要服務(wù)端回應(yīng)客戶端孙蒙,就和服務(wù)端一樣,我們還需要?jiǎng)?chuàng)建一個(gè)Handler并創(chuàng)建一個(gè)新的Messenger悲雳,并把這個(gè)Messenger對象通過Message的replyto參數(shù)傳遞給服務(wù)端挎峦,服務(wù)端通過這個(gè)replyTo參數(shù)就可以回應(yīng)客戶端了。
2.4.4使用AIDL
Messenger是以串行的方式去處理客戶端發(fā)來的消息合瓢,如果大并發(fā)坦胶,那么Messenger久不太合適了。這時(shí)候需要使用AIDL
2.5Binder連接池