Binder是一个深入的话题,由于Binder太过于复杂,所以本文不涉及底层细节,要想要知道底层细节可以去阅读Android Bander设计与实现 - 设计篇、写给 Android 应用工程师的 Binder 原理剖析这两篇文章。
1、AIDL文件的创建及解析
Binder使用起来还是比较简单的,创建一个IBinderPool.aidl文件然后clean
一下,就可以给我们生成一个Java文件。
// IBinderPool.aidl
package com.example.binder.aidl;
interface IBinderPool {
IBinder queryBinder(int binderCode);
}
生成的Java文件如下:
/*
* This file is auto-generated. DO NOT MODIFY.
* Original file: D:\\AndroidDemo\\BinderDemo\\app\\src\\main\\aidl\\com\\example\\binder\\aidl\\IBinderPool.aidl
*/
package com.example.binder.aidl;
// Declare any non-default types here with import statements
public interface IBinderPool extends android.os.IInterface {
/**
* Local-side IPC implementation stub class.
*/
public static abstract class Stub extends android.os.Binder implements com.example.binder.aidl.IBinderPool {
//Binder的唯一标识符,一般用当前Binder的类名表示,比如这里的com.example.binder.aidl.IBinderPool
private static final java.lang.String DESCRIPTOR = "com.example.binder.aidl.IBinderPool";
/**
* Construct the stub at attach it to the interface.
*
*/
public Stub() {
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an com.example.binder.aidl.IBinderPool interface,
* generating a proxy if needed.
* 用于将服务端的Binder对象转换成客户端所需的AIDL接口类型对象,这种类型转换过程是区分进程的,如果客户端和服务端位于同一进程,那么此方法返回的就是服务端的Stub对象本身,否则返回的是系统封装后的Stub.proxy对象
*/
public static com.example.binder.aidl.IBinderPool asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
//查询本地接口
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
//如果存在直接返回该对象(代表服务端与客户端在同一进程)
if (((iin != null) && (iin instanceof com.example.binder.aidl.IBinderPool))) {
return ((com.example.binder.aidl.IBinderPool) iin);
}
//返回系统封装后的Stub.proxy对象(代表服务端客户端不在同一进程)
return new com.example.binder.aidl.IBinderPool.Stub.Proxy(obj);
}
//返回当前的Binder对象
@Override
public android.os.IBinder asBinder() {
return this;
}
//该方法运行在服务端的Binder线程池中,当客户端发起跨进程请求时,远程请求会通过系统底层封装后交由此方法处理
@Override
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
switch (code) {
case INTERFACE_TRANSACTION: {
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_queryBinder: {
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
android.os.IBinder _result