ActivityThread,内部类ApplicationThread继承了ApplicationThreadNative,用于接收AMS的消息回调。而ApplicationThreadNative实则是继承了Binder类,重写了asInterface,onTransact等方法:
/** {@hide} */
public abstract class ApplicationThreadNative extends Binder
implements IApplicationThread {
/**
* Cast a Binder object into an application thread interface, generating
* a proxy if needed.
*/
static public IApplicationThread asInterface(IBinder obj) {
if (obj == null) {
return null;
}
IApplicationThread in =
(IApplicationThread)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
return new ApplicationThreadProxy(obj);
}
public ApplicationThreadNative() {
attachInterface(this, descriptor);
}
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags){
//处理各种AMS的回调
}
}
ContentProvider也是类似实现。内部Transport类继承自ContentProviderNative,ContentProviderNative也是一个继承自Binder的类。不止于此,其它还有很多类似的例子。
当我们通过aidl定义远程调用接口后,aidl.exe工具会帮助我们生成Binder调用模板代码,继承Stub类实现接口方法,可以用在服务端,在Service的onBinder方法返回Stub子类实现的对象。模板代码也用于客户端,主要使用asInterface,将远程调用Binder传入Proxy类,生成远程Binder的调用代理 。
aidl的方式,大大方便和简化了应用开发者使用Binder的难度。只需要按aidl的语法定义接口,就能自动生成规范的服务端与客户端进行Binder调用的代码。
aidl文件
interface IMultiCPCallback {
String getUUID();
}
Service中bindService的时候,获取远程Binder调用代理。asInterface会将传入service(也就是远程Binder对象)到Proxy类中,Proxy类实现了CPCallback,用户通过mCPCallback调用的操作,都传递给了Proxy,Proxy持有远程调用Binder对象,Proxy通过调用远程调用Binder的对象,就可完成远程Binder调用。
private CPCallback mCPCallback;
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
mCPCallback=null;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mCPCallback = CPCallback.Stub.asInterface(service);
}
};
生成的Binder调用代码。
/*
* This file is auto-generated. DO NOT MODIFY.
* Original file: D:\\MulticpSdk\\multicplibrary\\src\\main\\aidl\\com\\panxw\\aidl\\CPInterface.aidl
*/
package com.panxw.aidl;
public interface CPInterface extends android.os.IInterface {
/**
* Local-side IPC implementation stub class.(Client,也就是本地Binder实现类)
*/
public static abstract class Stub extends android.os.Binder implements com.panxw.aidl.CPInterface {
private static final java.lang.String DESCRIPTOR = "com.panxw.aidl.CPInterface";
/**
* Construct the stub at attach it to the interface.
*/
public Stub() {
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an com.panxw.aidl.CPInterface interface,
* generating a proxy if needed.
*/
public static com.panxw.aidl.CPInterface asInterface(android.os.IBinder obj) {//服务连接后,获取远程Binder的调用代理。
if ((obj == null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof com.panxw.aidl.CPInterface))) {
return ((com.panxw.aidl.CPInterface) iin);
}
return new com.panxw.aidl.CPInterface.Stub.Proxy(obj); //通过远程Binder对象obj生成远程调用代理类。
}
@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 {
java.lang.String descriptor = DESCRIPTOR;
switch (code) {
case INTERFACE_TRANSACTION: {
reply.writeString(descriptor);
return true;
}
case TRANSACTION_getUUID: {
data.enforceInterface(descriptor);
java.lang.String _result = this.getUUID();//服务端Service继承Stub,实现定义服务接口,生成Binder对象,返回给onBinder
reply.writeNoException();
reply.writeString(_result);
return true;
}
default: {
return super.onTransact(code, data, reply, flags);
}
}
}
private static class Proxy implements com.panxw.aidl.CPInterface {
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote) {//参数就是远程Binder对象引用
mRemote = remote;
}
@Override
public android.os.IBinder asBinder() {
return mRemote;
}
public java.lang.String getInterfaceDescriptor() {
return DESCRIPTOR;
}
@Override
public java.lang.String getUUID() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
java.lang.String _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_getUUID, _data, _reply, 0);//调用getUUID,能过远程Binder调用对象引用,向远程服务发起调用请求。
_reply.readException();
_result = _reply.readString();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_getUUID = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
}
public java.lang.String getUUID() throws android.os.RemoteException;
}