实现IPC,为什么要用AIDL?
Binder 机制是 Android 系统实现 IPC 的底层原理,通常只在系统源码中进行使用,而应用层开发,要进行 IPC 时,直接使用Binder太繁琐了。因此谷歌为我们设计出了 AIDL,全称是 Android Interface Definition Language(接口定义语言),相当于 Binder 机制在应用层的封装。AIDL支持一对多的并发实时通信。
AIDL与Binder类有什么关系?
AIDL是一个机制,这个机制通过Service完成跨进程通信,客户端启动服务端进程的Service后,需要获取Service对象,这个对象由IBinder接口对象提供,这个IBinder接口就是Binder类的父类。详细请看:Activity如何与Service通信?。
客户端和服务端分别做了什么?
- 服务端新建IPerson.aidl文件,编译得到IPerson.java接口文件。新建一个接口实现类 PersonImpl,让其继承刚刚自动生成的类里面的 IPerson.Stub 抽象类,并实现接口里面的抽象方法。新建一个服务类 MyService ,让其继承自 Service,并在 onBind 方法中返回上一步的实现(PersonImpl)的实例。在 manifest.xml 文件中给 MyService 服务定义一个 action ,至此服务端代码写完了.
- 客户端复制同一份IPerson.aidl文件,编译得到IPerson.java接口,接口内部包含一个普通类Default和一个抽象类Stub。IPerson接口对应的对象,由
IPerson.Stub.asInterface(binder);
产生,再通过该对象,获取服务端提供的数据。
asInterface是如何产生对象的?
下面是另外一个编译后自动生成的,IPerson.Stub类的
public static com.willhua.demoaidl.aidl.IBookManager asInterface(
android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof com.willhua.demoaidl.aidl.IBookManager))) {
return ((com.willhua.demoaidl.aidl.IBookManager) iin);
}
return new com.willhua.demoaidl.aidl.IBookManager.Stub.Proxy(obj);
}
我们知道asInterface的作用是根据调用是否属于同进程而返回不同的实例对象,但是对于该过程是怎么进行的?返回的到底是什么东西?显然,通过代码可知,决定返回何种对象的关键在obj.queryLocalInterface(DESCRIPTOR)
的返回结果。obj的类型是Binder,继续看Binder的源码:
public class Binder implements IBinder {
//...
/**
* Convenience method for associating a specific interface with the Binder.
* After calling, queryLocalInterface() will be implemented for you
* to return the given owner IInterface when the corresponding
* descriptor is requested.
*/
public void attachInterface(IInterface owner, String descriptor) {
mOwner = owner;
mDescriptor = descriptor;
}
/**
* Use information supplied to attachInterface() to return the
* associated IInterface if it matches the requested
* descriptor.
*/
public IInterface queryLocalInterface(String descriptor) {
if (mDescriptor.equals(descriptor)) {
return mOwner;
}
return null;
}
//...
final class BinderProxy implements IBinder {
//...
public IInterface queryLocalInterface(String descriptor) {
return null;
}
//...
}
}
精力有限,还有许多其他疑问,日后再补充!
说明一下JNI 与AIDL
Android:学习AIDL,这一篇文章就够了(上)
AndroidStudio 中 AIDL 使用实战以及采坑总结
Binder中的asInterface解析
Binder浅析-AIDL调用流程
android开发AIDL实例
Binder学习指南
写给 Android 应用工程师的 Binder 原理剖析