Binder是Android的一个类,从IPC角度来说,他是一种跨进程通信的方式;从Andtoid Framework角度来说,Binder是ServiceManager连接各种Manager(ActivityManager,WindowsManager)和响应ManagerService的桥梁;从Android应用层来说,Binder是客户端和服务端进行通信的媒介,当bindService时,服务端会返回一个包含了服务端业务调用的Binder对象,通过这个对象,客户端可以获取服务端提供的服务或者数据,这里的服务包括普通服务和AIDL服务。
以下是系统自动生成的TestAidl.java,TestAidl中只有一个int add(int num1,int num2);的方法。
/*
* This file is auto-generated. DO NOT MODIFY.
* Original file: D:\\software\\adt-bundle-windows-x86-20140321\\adt-bundle-windows-x86-20140321\\eclipse\\d\\Users\\wangjy.fnst\\workspace\\AlarmTest\\src\\com\\example\\parcelable\\TestAidl.aidl
*/
package com.example.parcelable;
// 继承IInterface并且自己也是一个接口
// 声明了一个内部类Stub,Stub就是Binder类,当客户端与服务端位于同一个进程,方法调用不会走Transact
// 两者位于不同进程时需要走Transact过程,这个逻辑由Stub的内部代理类Proxy来实现
public interface TestAidl extends android.os.IInterface {
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements
com.example.parcelable.TestAidl {
// Binder的唯一标识,一般用当前Binder的类名
private static final java.lang.String DESCRIPTOR = "com.example.parcelable.TestAidl";
/** Construct the stub at attach it to the interface. */
public Stub() {
this.attachInterface(this, DESCRIPTOR);
}
/**
* 用于将服务端的Binder对象转换成客户端使用的AIDL接口类型的对象
* 如果位于同一进程返回Stub本身,否则返回系统封装的Stub.proxy对象
*/
public static com.example.parcelable.TestAidl asInterface(
android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof com.example.parcelable.TestAidl))) {
return ((com.example.parcelable.TestAidl) iin);
}
return new com.example.parcelable.TestAidl.Stub.Proxy(obj);
}
// 返回当前Binder对象
@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 {
// code用来标示在Transact过程中客户端所请求的是哪个方法
// 从data中获取目标方法所需的参数,执行完毕向reply写入结果
// 如果此方法返回false,代表客户端请求失败,可以利用这个特征来做权限验证
switch (code) {
case INTERFACE_TRANSACTION: {
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_add: {
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
int _arg1;
_arg1 = data.readInt();
int _result = this.add(_arg0, _arg1);
reply.writeNoException();
reply.writeInt(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements com.example.parcelable.TestAidl {
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote) {
mRemote = remote;
}
@Override
public android.os.IBinder asBinder() {
return mRemote;
}
public java.lang.String getInterfaceDescriptor() {
return DESCRIPTOR;
}
// TestAidl中声明的int add(int num1, int num2);方法
@Override
public int add(int num1, int num2)
throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(num1);
_data.writeInt(num2);
mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_add = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
}
public int add(int num1, int num2) throws android.os.RemoteException;
}
// 注意
// 如果一个远程方法很耗时,不能在UI线程中发起远程请求
// 由于服务端Binder方法运行在Binder线程池,所以Binder方法不管是否耗时都应采用同步方式实现,因为他已经运行在一个线程了
以下是Binder的工作机制: