要想使用服務端,首先要獲取服務端在binder驅動中對應的mremote變數的引用。獲得該變數的引用後,就可以呼叫該變數的transact()方法。該方法的函式原型如下:
public final boolean transact(int code, parcel data, parcel reply,int flags)
其中data表示的是要傳遞給遠端binder服務的包裹(parcel),遠端服務函式所需要的引數必須放入這個包裹中。包裹中只能放入特定型別的變數,這些型別包括常用的原子型別,比如string、int、long等,要檢視包裹可以放入的全部資料型別,可以參照parcel類。除了一般的原子變數外,parcel還提供了乙個writeparcel()方法,可以在包裹中包含乙個小包裹。因此,要進行binder遠端服務呼叫時,服務函式的引數要麼是乙個原子類,要麼必須繼承於parcel類,否則,是不能傳遞的。
因此,對於musicplayerservice的客戶端而言,可以如下呼叫transact()方法。
ibinder mremote = null;
string filepath = "/sdcard/music/heal_the_world.***";
int code = 1000;
parcel data = parcel.obtain();
parcel reply = parcel.obtain();
data.writeinte***cetoken("musicplayerservice");
data.writestring(filepath);
mremote.transact(code, data, reply, 0);
ibinder binder = reply.readstrongbinder();
reply.recycle();
data.recycle();
現在來分析以上**。首先,包裹不是客戶端自己建立的,而是呼叫parcel.obtain()申請的,這正如生活中的郵局一樣,使用者一般只能用郵局提供的信封(尤其是ems)。其中data和reply變數都由客戶端提供,reply變數使用者服務端把返回的結果放入其中。
writeinte***cetoken()方法標註遠端服務名稱,理論上講,這個名稱不是必需的,因為客戶端既然已經獲取指定遠端服務的binder引用,那麼就不會呼叫到其他遠端服務。該名稱將作為binder驅動確保客戶端的確想呼叫指定的服務端。
writestring()方法用於向包裹中新增乙個string變數。注意,包裹中新增的內容是有序的,這個順序必須是客戶端和服務端事先約定好的,在服務端的ontransact()方法中會按照約定的順序取出變數。
接著呼叫transact()方法。呼叫該方法後,客戶端執行緒進入binder驅動,binder驅動就會掛起當前執行緒,並向遠端服務傳送乙個訊息,訊息中包含了客戶端傳進來的包裹。服務端拿到包裹後,會對包裹進行拆解,然後執行指定的服務函式,執行完畢後,再把執行結果放入客戶端提供的reply包裹中。然後服務端向binder驅動傳送乙個notify的訊息,從而使得客戶端執行緒從binder驅動**區返回到客戶端**區。
transact()的最後乙個引數的含義是執行ipc呼叫的模式,分為兩種:一種是雙向,用常量0表示,其含義是服務端執行完指定服務後會返回一定的資料;另一種是單向,用常量1表示,其含義是不返回任何資料。
最後,客戶端就可以從reply中解析返回的資料了,同樣,返回包裹中包含的資料也必須是有序的,而且這個順序也必須是服務端和客戶端事先約定好的。
核心研究 客戶端中的執行緒
static class w extends iwindow.stub為了驗證這一點,可以在eclipse中新建乙個hello android的程式,然後以debug的方式執行,在debug視窗中會看到如圖所示的介面。自定義thread和ui執行緒的區別在於,ui執行緒是從activitythrea...
核心研究 Binder框架概述
binder工作在linux層面,屬於乙個驅動,只是這個驅動不需要硬體,或者說其操作的硬體是基於一小段記憶體。從執行緒的角度來講,binder驅動 執行在核心態,客戶端程式呼叫binder是通過系統呼叫完成的。binder是一種架構,這種架構提供了服務端介面 binder驅動 客戶端介面三個模組,如...
XMPP核心協議客戶端
xmpp就是jabber協議的正式名稱。其核心協議就是乙個通過socket等媒介傳送xml的規範。非常簡單,好實現。先是通過socket建立乙個網路連線 然後客戶端向伺服器傳送乙個這樣的xml開始標籤 然後伺服器會返回乙個這樣的標籤,作為握手訊號 然後這就標誌著雙方可以開始xml流的互通了 斷開似乎...