网上讲解Aidl的文章很多,都比较详细,这里就不再重复了。本人更偏重与Framework和Native,对APP没有发言权,文章中可能出现错误,请理解。这篇侧重于一下表面看不到的实现,碎片化的做些分析。
Binder Stub
Stub是Binder服务端的对象,用来做为对Binder实体的描述。在Aidl生成的Java文件中,Stub类被创建,一个简单的示例如下。
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements com.aidltest.aidlserver.IAidlInterface
{
private static final java.lang.String DESCRIPTOR = "com.aidltest.aidlserver.IAidlInterface";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an com.aidltest.aidlserver.IAidlInterface interface,
* generating a proxy if needed.
*/
public static com.aidltest.aidlserver.IAidlInterface asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.aidltest.aidlserver.IAidlInterface))) {
return ((com.aidltest.aidlserver.IAidlInterface)iin);
}
return new com.aidltest.aidlserver.IAidlInterface.Stub.Proxy(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
{
......
重要的接口说明如下,
- asInterface:获取Binder代理,如果不存在这新建一个Proxy对象返回。
- asBinder:获取Binder实体,服务端直接返回this。
- onTransact:Binder传输接口,Aidl自动生成了传输命令,服务端仅需要实现Aidl中声明的函数。
通常情况下,服务端在初始化时会创建一个Stub对象作为Binder实体,在onBinder()将其返回,这样客户端就可以获取到Binder实体。
Binder Proxy
Proxy为Binder客户端的对象,做为Binder代理进行跨进程调用。Aidl生成的代码如下,
private static class Proxy implements com.aidltest.aidlserver.IAidlInterface
{
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;
}
@Override public int add(int a, int b) throws android.os.RemoteException
{
......
重要接口如下,
- asBinder:获取Binder实体,客户端返回remote。
- getInterfaceDescriptor:获取Binder的服务接口描述。
客户端在bindService成功后会回调到客户端的onServiceConnected(),同时返回Binder实体。之后就可以调用Stub.asInterface()将Binder实体转换为Binder代理。
调用流程
整个Aidl调用流程比较简单,其中涉及bindService流程在之前的文章中已经分析过。
通过Aidl进行跨进程通信时实现非常简单,只需要按Aidl中限定的接口在服务端进行实现,就可以通过客户端进行调用。复杂的连接过程和传输过程已经被底层屏蔽。如果仅仅时使用Aidl,实际上可以不需要理解Binder。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。