Binder具有被跨进程传输的能力是因为它实现了IBinder
接口。系统会为每个实现了该接口的对象提供跨进程传输。
1. Service端声明一个 extends Service类,在该类中声明一个继承自Binder类(实现iBinder接口)的内部类,这个类需要实现需要暴露给client端的方法;重写onBind方法,在这个方法中返回创建的内部类对象(也是个Binder对象)。
@Override
public IBinder onBind(Intent intent) {
// Return the interface
return mBinder;
}
在AIDL中,这个内部类也是个抽象类,统一命名为Stub并且implements了一个接口,这个接口定义了所有service端暴露给client端的方法。
private final IxxxService.Stub mBinder = new IxxxService.Stub() {
public Stub() {
this.attachInterface(this, DESCRIPTOR);//使当前的Binder对象持有当前Service的引用,并设定一个标识符,这样在调用queryLocalInterface通过该标识符可以获得该service的引用
}
/**
* Cast an IBinder object into an com.telenav.arp.service.IxxxService interface,
* generating a proxy if needed.
*/
public static com.telenav.arp.service.IxxxService asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof com.telenav.arp.service.IxxxService))) {
return ((com.telenav.arp.service.IxxxService) iin);
}
return new com.telenav.arp.service.IxxxService.Stub.Proxy(obj);//Binder对象的代理,可以把client端的请求进行transact。
}
@Override
public android.os.IBinder asBinder() {
return this;
}
@Override
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
switch (code) {
。。。。。。
}}
Binder
对象可通过attachInterface
方法持有一个IInterface
对象(即plus
)的引用,并依靠它获得完成特定任务的能力。queryLocalInterface
方法可以认为是根据key
值(即参数 descriptor
)查找相应的IInterface
对象。
2. client bindService(Intent intent, ServiceConnection conn, int flags)
3. client bind成功,触发ServiceConnection onServiceConnected(ComponentName name, IBinder service),得到从 service端的onBind() 方法中返回的 Binder 对象。
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
synchronized (this) {
this.mService = IxxxService.Stub.asInterface(service);
}
}
4. client端通过获取到的Binder对象引用调用service端的某个方法
5. client端的数据和请求通过IBinder的transtact方法转化以后传递给Binder对象,Binder对象收到请求,调用onTransact方法执行service端的相应方法,得到结果后再传递回client端。
API的解释如下
* <p>The key IBinder API is {@link #transact transact()} matched by
* {@link Binder#onTransact Binder.onTransact()}. These
* methods allow you to send a call to an IBinder object and receive a
* call coming in to a Binder object, respectively. This transaction API
* is synchronous, such that a call to {@link #transact transact()} does not
* return until the target has returned from
* {@link Binder#onTransact Binder.onTransact()}; this is the
* expected behavior when calling an object that exists in the local
* process, and the underlying inter-process communication (IPC) mechanism
* ensures that these same semantics apply when going across processes.
*
参考文献:
http://www.jianshu.com/p/9a13f1afbc6e
Android Binder 完全解析(三)AIDL实现原理分析
http://www.woaitqs.cc/android/2016/05/26/android-binder-token
Android Binder 全解析(2) -- 设计详解
http://www.jianshu.com/p/c11333e77910
Android Binder 完全解析(一)概述
http://www.jianshu.com/p/1eff5a13000d
可能是讲解Binder机制最好的文章