Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android Binder講解

android Binder講解

編輯:關於Android編程

Binder用於完成進程間通信(IPC),即把多個進程“別”在一起,從線程的角度來講,Binder驅動代碼運行在內核態,客戶端程序調用Binder是通過系統調用完成的。Binder是一種架構,這種架構提供了服務端接口、Binder驅動、客戶端接口三個模塊。

\

重載onTransactO函數的主要內容是把onTmnSact()函數的參數轉換為服務函數的參數,而onTransact()函數的參數來源是客戶端調用transact()函數時輸入的。<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+yM7S4tK7uPa3/s7xtstCaW5kZXK21M/zsbu0tL2oyrGjrM2syrG74dTaQmluZGVyx/22r9bQtLS9qNK7uPY8L3A+CjxwPm1SZW1vdGW21M/zo6y4w7bUz/O1xMDg0M3SssrHQmluZGVywOCho7/Nu6e2y9Kqt8POytS2s8y3/s7xyrGjrLa8ysfNqLn9bVJlbW90ZbbUz/Oho7/Nu6e2yyYjMjAyODQ7uvXKx9axvdO199PD1LazzLf+zvG21NOmtcRCaW5kZXKjrLb4ysLKtcnP1PLKx82ouf1CaW5kZXLH/bavvfjQ0MHL1tDXqqGjvLS05tTawb249kJpbmRlcrbUz/OjrNK7uPbKx7f+zvG2y7XEQmluZGVyttTP86Oswe3Su7j21PLKx0JpbmRlcsf9tq/W0LXEQmluZGVyttTP86Osy/myu82stcTKx0JpbmRlcsf9tq/W0LXEttTP87K7u+HU2bbuzeKy+sn60ru49s/fs8yhozwvcD4KPGgyPrf+zvG2y8novMY8L2gyPgo8cHJlIGNsYXNzPQ=="brush:java;">Public class MusicPlayService extends Binder{ /** * MusicPlayServicemusicPlayService=newMusicPlayService();會開啟一個新線程 * code:是客戶端與服務端約定的,代表變量存取的編號(多個變量公用一個編號) * data:客戶端數據存放 * replay:服務端返回的數據存放 * flag:IPC調用的模式 * 一種是雙向,用常量0表示,其含義是服務端執行完指定服務後會返回一定的數據; * 一種是單向,用常量1表示,其含義是不返回任何數據。 */ @Override Protected boolean onTransact(int code,Parcel data,Parcel reply,int flags) throws RemoteException{ switch(code){ case1000: //為了某種校驗,它與客戶端的writeInterfaceToken()對應 data.enforceInterface("MusicPlayService"); String arg=data.readString(); String arg1 = data.readString(); break; case2000: data.enforceInterface("MusicPlayService"); arg=data.readString(); break; } returnsuper.onTransact(code,data,reply,flags); } publicvoidstart(){ } publicvoidstop(){ } }

Binder驅動

當創建一個Binder對象時,服務端進程內部創建一個Binder對象,Binder驅動中也會創建一個Binder對象。如果從遠程獲取服務端的Binder,則只會返回Binder驅動中的Binder對象,而如果從服務端進程內部獲取Binder對象,則會獲取服務端本身的Binder對象。

客戶端設計

publicclassMusicPlayClient{

/**

* 兩個問題:

* 1、客戶端如何獲得服務端的Binder對象引用?

*為什麼使用Binder?為了提供一個全局服務,系統的任何應用程序都可以使用,解決方案就是用service服務

* 2、客戶端和服務端必須事先約定好兩件事情:服務端函數的參數在包裹中的順序、服務端不同函數的int型標識

*

*service是如何解決上述兩個問題

*第一個問題:

*客戶端通過binderService和startService來啟動服務

*bindService(service,conn,flags)和StartService(service)

*ServiceConnection{

*onServiceConnected(ComponentNamename,IBinderservice);

*}

*通過bind來綁定服務,如果service啟動成功,ActivityManagerService就會調用ActivityThread類中的ApplicationThread對象,調用的參數中會包含service的Binder引用,然後再ApplicationThread中回調bindService中的conn接口,客戶端可將其設為全局變量。

*第二個問題:

*Androidsdk中提供了aidl工具,可以把一個aidl文件轉化成java類,其重載了transact和onTransact方法,統一了包裹存放和包裹讀取的參數

*Proxy:客戶端訪問服務端的代理,統一包裹參數寫入的順序

*Stub:由服務端使用

*當創建一個Binder對象時,服務端進程內部創建一個Binder對象,Binder驅動中也會創建一個Binder對象。如果從遠程獲取服務端的Binder,則只會返回Binder驅動中的Binder對象,而如果從服務端進程內部獲取Binder對象,則會獲取服務端本身的Binder對

*/

Public void sendPacket()throwsRemoteException{

IBinde rmRemote=null;

String arg="agr0";

Parcel data=Parcel.obtain();

Parcel reply=Parcel.obtain();

data.writeInterfaceToken("MusicPlayService");//標注遠程服務名稱

data.writeString(arg);

Int flags=0;

/**

*客戶端線程進入Binder驅動,Binder驅動就會掛起當前線程,並向遠程服務發送一個消息,

*消息中包含了客戶端傳進來的包裹。服務端拿到包裹後,會對包裹進行拆解,然後執行指定的服務函數,

*執行完畢後,再把執行結果放入客戶端提供的reply包裹中。然後服務端向Binder驅動發送一個notify的消息,

*從而使得客戶端線程從Binder驅動代碼區返回到客戶端代碼區。

*/

mRemote.transact(1,data,reply,flags);

IBinderbinder=reply.readStrongBinder();

data.recycle();

reply.recycle();

}

}


  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved