上篇文章深刻理解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