最近研究了一下Android進程間通訊,原來只是會用,但是只是會用是不行滴,就來研究一下。
剛開始看的時候,我的頭是這么大
,看了一夜的時候,頭就變成這樣了,
,嚇得寶寶趕緊上床休息了,、
先喝喝茶講個故事再來說這個通訊。
(寫完之后,看到這個終于承認了自己寫作的能力很爛,但是好歹也是自己一個一個敲上去的,不能白白辛苦啊,嘿嘿)
-----------------------------------------------------------------------------------------------------------------
話說我有一哥們,最近他前女友來找他復(fù)合,但是他現(xiàn)在有女友,所以很是煩惱,整天吃不好睡不著,所以他打算問問上帝有什么好主意,可是為了安全起見,他又不能直接去找上帝,總不能一天死個5,6次吧,人生是沒有bug的。那怎么辦呢,幸好這世上還有一種生物叫神父,然后他就去找神父。
“father ,我最近很煩惱,你可以幫我問問上帝該怎么辦嗎”
“oh my son 上帝是萬能的,他可以幫我們解決任何問題,有什么就說吧”
“我現(xiàn)在有女朋友了,可是我的前女友最近又來找我復(fù)合,兩個都對我很好,我該怎么辦呢。。。。。(此處省略N多字)”
神父把上帝從睡夢中喊醒“上帝啊,這人有病啊,有兩個女的都喜歡他,直接收了不就完了,他還在糾結(jié)該選那個,您看這個怎么辦才好呢”
“哦,這件事我知道,他不是有個好朋友叫楊XX嗎,我已經(jīng)施法讓他的前女友喜歡上楊XX了,哈哈”
“son,上帝已經(jīng)施法讓你的前女友喜歡上了別人,是你的一個好朋友楊XX,你看這樣好不”
。。。。。。。。。。
情景轉(zhuǎn)到籃球場,我正在一群少女的歡呼中揮灑魅力,突然被一個手臂一拉。
“XX,你知道我最近很煩心的那個事嗎?”
我正因為被他從少女的崇拜中打攪不爽“不就是那個前女友嗎,怎么了”
“哈哈,我今天去找上帝,上帝已經(jīng)幫我解決了”
“哦,怎么解決的,看你高興的”
“上帝施法讓我的前女友喜歡你了”
我眼前一黑,一口心血噴出“上帝,臥槽你X“
我的女友是跆拳道黑帶三段。
---------------------------------------------------------------------------------------------------------------
(我又看了一遍,這個故事的確有點扯。。。。)
好了,忘掉吧,你可能會感到這個故事跟進程間通訊半毛錢關(guān)系沒有,但我感覺還是挺好的。。
Android進程間通訊,
為什么不能直接跨進程進行通訊啊?
因為,為了安全考慮。Android系統(tǒng)中,應(yīng)用所在的內(nèi)存是獨立的,無法相互訪問,各個應(yīng)用的數(shù)據(jù)都在自己的內(nèi)存中。
那么如何跨進程進行通訊呢?
要想跨進程,必須找一個公共的大家都能訪問的地方,通過暗號來達到通訊的目的。
Android中的跨進程通訊采用的是binder機制。
那么什么是binder呢,這個工作原理是什么呢,
Binder呢,其實就是一塊內(nèi)存,它在Linux層面屬于一個驅(qū)動,但是這個驅(qū)動不是驅(qū)動硬件,而是驅(qū)動一塊內(nèi)存。不同的應(yīng)用通過對一塊公共的內(nèi)存進行數(shù)據(jù)的讀寫,來達到通訊的目的。而且應(yīng)用之間進行通訊,
必須要有暗號(沒有暗號就成了火鍋,亂套了!),當(dāng)兩個應(yīng)用持有相同的暗號(AIDL時),才可以進行通訊。
知道了為什么跨,怎么跨,那么具體步驟怎么寫呢?
由于不是本文重點,請看官方開發(fā)文檔,現(xiàn)在開發(fā)文檔越來越詳細,估計人家美國12歲的小學(xué)生都能隨便開發(fā)一個簡單的應(yīng)用。唉 英語啊。
知道了以上這些東西,可是binder是怎么工作的,卻還不知道,接下來為大家介紹一下binder的工作原理。
在Android系統(tǒng)中的binder機制中,分別由Client,Server,ServiceManager和Binder驅(qū)動程序組成,其中Client、Server和Service Manager運行在用戶空間,Binder驅(qū)動程序運行內(nèi)核空間。Binder驅(qū)動程序是核
心組件, Service Manager是一個守護進程,用來管理Server,并向Client提供查詢Server接口的功能,開發(fā)者只需要在用戶空間實現(xiàn)自己的Client和Server即可。而Client和Server正是在Binder驅(qū)動和ServiceManager提供的基礎(chǔ)設(shè)施上,進行通信的。
binder工作原理:
binder通信是一種client-server的通信結(jié)構(gòu),
1.從表面上來看,是client通過獲得一個server的代理接口,對server進行直接調(diào)用;
2.實際上,代理接口中定義的方法與server中定義的方法是一一對應(yīng)的;
3.client調(diào)用某個代理接口中的方法時,代理接口的方法會將client傳遞的參數(shù)打包成為Parcel對象;
4.代理接口將該Parcel發(fā)送給內(nèi)核中的binder driver.
5.server會讀取binder driver中的請求數(shù)據(jù),如果是發(fā)送給自己的,解包Parcel對象,處理并將結(jié)果返回;
6.整個的調(diào)用過程是一個同步過程,在server處理的時候,client會阻塞
直接看不好理解,還好有圖。
前面已經(jīng)說過,Service Manager組件是用來管理Server并且向Client提供查詢Server遠程接口的功能,那么,Service Manager就必然要和Server以及Client進行通信了。然而,Service Manager、Client和
Server三者分別是運行在獨立的進程當(dāng)中,這樣它們之間的通信也屬于進程間通信了,而且也是采用Binder機制進行進程間通信,因此,ServiceManager在充當(dāng)Binder機制的守護進程的角色的同時,也在充當(dāng)Server
的角色,也就是說,它是一種特殊的Server。
其實在平時開發(fā)中,系統(tǒng)服務(wù)就是通過Binder機制來和應(yīng)用通訊的,接下來為大家詳細解釋一下系統(tǒng)服務(wù)和應(yīng)用通訊流程,以幫助大家更容易深刻的理解binder機制。
系統(tǒng)服務(wù)和應(yīng)用的通信機制
系統(tǒng)服務(wù):
1.是一個Binder類的子類,一旦創(chuàng)建后,就開啟一個線程死循環(huán)用來檢測某段內(nèi)存是否有數(shù)據(jù)寫入。
2.它自身創(chuàng)建時,創(chuàng)建一個xxxRemote遠程對象,存放到Binder驅(qū)動中,xxxRemote遠程對象可以和xxxService系統(tǒng)服務(wù)通信
應(yīng)用端:
通過context. getSystemService獲取xxxServiceProxy對象,該對象內(nèi)部引用了xxxRemote對象, xxxServiceProxy和xxxService具有相同的API,我們調(diào)用xxxServiceProxy時,xxxServiceProxy就調(diào)用
xxxRemote并等待xxxRemote返回。xxxRemote會往某段內(nèi)存中寫入數(shù)據(jù),寫完后就開始監(jiān)視該內(nèi)存區(qū)域,Binder驅(qū)動會把xxxRemote寫入的數(shù)據(jù)拷貝到xxxService監(jiān)視著的內(nèi)存區(qū)域,當(dāng)xxxService一旦發(fā)現(xiàn)有數(shù)
據(jù),就讀取并進行處理,處理完畢后,就寫入該區(qū)域,這時Binder驅(qū)動又會把該數(shù)據(jù)拷貝到xxxRemote監(jiān)視的內(nèi)存區(qū)域,當(dāng)xxxRemote發(fā)現(xiàn)內(nèi)存區(qū)域有數(shù)據(jù)讀取該區(qū)域數(shù)據(jù),并把內(nèi)容返回給xxxServiceProxy。這樣
就完成了一次進程間的通信。
所以一個系統(tǒng)服務(wù)會產(chǎn)生兩個Binder對象,一個是運行在系統(tǒng)中的系統(tǒng)服務(wù)本身,一個是存放到Binder驅(qū)動中的遠程對象。所不同的是系統(tǒng)服務(wù)Binder對象會開啟一個線程監(jiān)聽消息,遠程對象不會,它是運行在
調(diào)用者的線程中。
客戶端也可以不使用系統(tǒng)服務(wù)的遠程Binder對象,而是自己創(chuàng)建一個Binder對象,通過Binder驅(qū)動和系統(tǒng)服務(wù)進行關(guān)聯(lián),這樣的好處客戶端可以隨時通知系統(tǒng)服務(wù),系統(tǒng)服務(wù)也可以隨時通知客戶端,而不是像上
面所說的系統(tǒng)服務(wù)只能被動的等著客戶端調(diào)用。
那么binder內(nèi)部是怎么操作的
Binder對象都有各自的內(nèi)存區(qū)域,當(dāng)Binder1想要向Binder2發(fā)送數(shù)據(jù)時,就會把數(shù)據(jù)寫入自己的內(nèi)存區(qū)域,然后通知Binder驅(qū)動,Binder驅(qū)動會把數(shù)據(jù)拷貝到Binder2的內(nèi)存區(qū)
域,然后通知Binder2進行讀取,Binder2讀取完畢后,將把數(shù)據(jù)寫入binder2的內(nèi)存區(qū)域,然后通知Binder驅(qū)動,Binder驅(qū)動將會把數(shù)據(jù)拷貝到Binder1的內(nèi)存區(qū)域中。這樣就完成
了一次通信。
如果Binder1是系統(tǒng)服務(wù),Binder2是系統(tǒng)服務(wù)的遠程對象,這樣任何應(yīng)用程序在獲取了Binder2的引用后,都可以和Binder1進行通信。但是缺點也很明顯,只能由應(yīng)用端請求
系統(tǒng)服務(wù),系統(tǒng)服務(wù)不能主動去聯(lián)系應(yīng)用端。WifiManagerService之類的就是采用這種方式。
還有一種方式是Binder1是系統(tǒng)服務(wù),Binder2是應(yīng)用端創(chuàng)建的Binder對象,他們兩者通過Binder驅(qū)動進行連接后,應(yīng)用端可以主動調(diào)系統(tǒng)服務(wù),系統(tǒng)服務(wù)也可以主動調(diào)用應(yīng)用
端。WindowManagerService就是采用的這種方式。
我是看了很多資料才寫出的這篇博客,大家有興趣可以去看看http://blog.csdn.net/luoshengyang/article/details/6618363#comments的博客,的確大牛。