上篇文章深刻理解Binder(一),從AIDL談起咱們介紹了AIDL的基本使用,用AIDL兩個App的通訊是實現了,但是又有小夥伴疑惑了,爲何使用AIDL就可以實現兩個App之間的通訊?本文咱們就來詳細說說這個問題。java
Binder單從字面上理解,它有活頁夾,粘合劑的意思,活頁夾能夠用來把兩個東西夾在一塊兒。在咱們的Android系統中,Binder主要用來實現進程之間的通訊(IPC),它的主要做用就是把多個App夾在一塊兒。那麼這個Binder究竟是個什麼東西呢?其實它是一個工做在Linux層面的驅動,這一段驅動運行在內核態。咱們在客戶端調用Binder都是經過系統調用最終完成的。Binder自己又是一種架構,這種架構提供了服務端、Binder驅動和客戶端三個模塊。咱們用AIDL在服務端和客戶端生成的文件都是爲了完成服務端和客戶端的相關功能,OK,那麼接下來咱們就從服務端、Binder驅動、客戶端三個方面來分別分析Binder的工做原理。android
1.服務端架構
Binder服務端實際上就是一個Binder類的對象,當咱們建立一個Binder對象的時候,Binder內部就會啓動一個隱藏線程,該線程的主要做用就是接收Binder驅動發送來的消息,那麼Binder驅動爲何會給Binder服務端的線程發送消息呢?緣由很簡單,咱們在客戶端調用服務端的時候並不能直接調用服務端相應的類和方法,只能經過Binder驅動來調用。當服務端的隱藏線程收到Binder驅動發來的消息以後,就會回調服務端的onTransact方法,咱們來看看這個方法的方法頭:ide
protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException
public class MyAddBinder extends Binder { private final static int ADD = 1; @Override protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { switch (code) { case ADD: data.enforceInterface("MyAddBinder"); int a = data.readInt(); int b = data.readInt(); int add = add(a, b); reply.writeInt(add); return true; } return super.onTransact(code, data, reply, flags); } public int add(int a, int b) { return a + b; } }
public class MyService extends Service { @Nullable @Override public IBinder onBind(Intent intent) { return new MyAddBinder(); } }
2.Binder驅動工具
Binder驅動是Binder服務端和Binder客戶端之間鏈接的一個橋樑,當一個服務端Binder被建立出來的時候,系統同時會在Binder驅動中建立另一個Binder對象,當客戶端想要訪問遠程的Binder服務端的時候, 都是經過這個Binder對象來完成的。那麼Binder驅動中的這個對象要怎麼樣獲取呢?其實很簡單,這個BInder對象就是咱們用綁定的方式啓動一個Service服務時,在綁定成功時所獲取的那個IBinder對象。以下:google
boolean b = bindService(intent, new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { //這個service就是Binder驅動中建立的Binder對象 mRemote = service; } @Override public void onServiceDisconnected(ComponentName name) { } }, Service.BIND_AUTO_CREATE);
3.客戶端
spa
客戶端就簡單了,咱們首先須要在客戶端獲取Binder驅動中的Binder對象,而後調用該對象中的transact方法進行數據傳遞。客戶端在向服務端發送消息的時候是以線程間通訊的模式來進行的,並且調用服務端代碼是同步進行的,也就是說線程會阻塞。OK,基於此,咱們就來看看客戶端代碼該怎麼寫:.net
int code = 1; //向服務端發送的數據 Parcel data = Parcel.obtain(); //接收服務端返回的數據 Parcel reply = Parcel.obtain(); data.writeInterfaceToken("MyAddBinder"); data.writeInt(10); data.writeInt(9); try { mRemote.transact(code, data, reply, 0); int i = reply.readInt(); Log.d("google.sang", "add: " + i); reply.recycle(); data.recycle(); } catch (RemoteException e) { e.printStackTrace(); }
OK,通過上文的講解相信小夥伴們對Binder的工做機制已經有了一個大體的瞭解。線程
以上。
code