1

网上讲解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(1).png
通过Aidl进行跨进程通信时实现非常简单,只需要按Aidl中限定的接口在服务端进行实现,就可以通过客户端进行调用。复杂的连接过程和传输过程已经被底层屏蔽。如果仅仅时使用Aidl,实际上可以不需要理解Binder。


戈壁老王
143 声望60 粉丝

做为一个不称职的老年码农,一直疏忽整理笔记,开博记录一下,用来丰富老年生活,