Binder机制

前言

看了很多Binder通信机制的博客,一直搞不懂,讲的很复杂,看过《简单明了,彻底地理解Binder》后,大概明白了一些,但是感觉还是不容易理解

Binder的C/S架构


这张图描述了Binder基本流程,服务端注册服务,客户端查找到服务后开始请求

Binder 原理


上面了解了基本流程,这里介绍凭什么么能跨进程通信
1.注册服务:Server通过Binder驱动在ServiceManger中注册,在Manger中存放名称及Binder的引用(类似DNS)
2.查询服务:Client通过Binder驱动在ServiceManger中根据指定的名称查找Binder的引用,Interface.Stub.asInterface()
3.使用服务:Client获取到Binder引用后,调用其方法(即开始进程间通信,此时客户端线程被挂起),Client将数据写入到共享内存中,Binder驱动将Client的数据复制到远程进程的共享内存,远程进程执行onTransact()函数,根据方法的code调用不同的方法返回结果。远程端执行后将数据放入远程端与的共享内存,Binder驱动将返回结果复制到Client的共享内存区(唤起客户端线程)

AIDL使用

  1. 创建.aidl接口并创建要提供的方法
  2. 创建service进程,在onBind方法中返回Interface.Stub对象
  3. 创建ServiceConnection对象,调用Interface.Stub.asInterface(ibinder)
  4. bindService
  5. 调用接口中的方法

重要方法

asInterface

1
2
3
4
5
6
7
8
9
10
11
public static com.didi.sourcecodedemo.IMyAidlInterface asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.didi.sourcecodedemo.IMyAidlInterface))) {
return ((com.didi.sourcecodedemo.IMyAidlInterface)iin);
}
return new com.didi.sourcecodedemo.IMyAidlInterface.Stub.Proxy(obj);
}

如果是跨进程则返回代理对象,否则返回service中binder接口的对象,在obj.queryLocalInterface中判断DESCRIPTOR与Binder对象的DESCRIPTOR是否相等,相等创建binder接口的对象,不相等或者代理对象直接返回代理对象(远程进程返回代理对象继承自BinderProxy类,obj.queryLocalInterface直接return NULL
简单来说,客户端根据远程端返回的对象,创建代理对象(跨进程)或者Interface对象(非跨进程)

onTransact

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch (code)
{
case TRANSACTION_sendMessage:
{
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
java.lang.String _arg1;
_arg1 = data.readString();
java.lang.String _result = this.setMessage(_arg0, _arg1);
reply.writeNoException();
reply.writeString(_result);
return true;
}
}
}

服务端根据code判断客户端想要调用的方法,并读出数据,调用远程端中真正实现的方法并将结果写会reply