第一步 创建 aidl 接口文件 AndroidStudio 中直接右键创建,或者自己一步步建目录喽。 创建完成后会生成一个 在看接口怎么写前,先记住以下三点: 支持的参数类型
自定义引用类型使用如果要使用自定义的数据类型,需要先为它也生成一个aidl文件,里面内容只需两行: AIDL的包名;
parcelable 类名; 例如: package com.coorchice.coorchicelibone;
parcelable Role; 接着就可以创建对应的java数据类了,然后实现Parcelable接口,注意包名需要和aidl一模一样!如果你对自定义类型使用了in或者inout标识符的话,你必须再给自定义类实现 public void readFromParcel(Parcel in) {
name = in.readString();
skill = in.readString();
} 然后在定义 aidl 接口时,一定要记得手动写一下自定义引用类的import! 参数修饰符
定义服务接口现在,我们可以开始定义服务接口了!这里定义的服务接口就是后面我们需要在客户端调用的。 CoorChice 定义了3个接口,接着编译一下。然后编译器会自动根据我们定义的接口生成对应的类。
编译后生成的类解析编译之后编译器自动帮我们生成了一个 其实,Android 的 AIDL 就是让编译器帮助我们生成一个实现了我们接口的 Binder,以帮助我们简化开发。当然,如果你了解原理的话,也可以自己写。 下面我们一步一步来看看这编译器生成的类都有些什么? 1. 服务接口实现IInterfacepublic interface AIDLDemo extends android.os.IInterface
{
...
} 编译器根据我们写的服务接口,重新生成了一个接口,唯一的区别就是新的接口继承了 public interface IInterface
{
public IBinder asBinder();
} 可以看到,它只有一个接口方法。这个方法用来定义将实现接口的类应该具备返回一个与之相关联的Binder的功能,以提供通讯能力。一般实现这个方法的类自己本身就会去继承Binder。 这样的设计使得Binder机制不用关心具体的接口是什么,只要是 2. 继承Binder,实现服务接口要进行 Binder 通讯,我们自然需要一个 Binder;要实现我们定义的服务接口功能,自然就需要实现服务接口。那么需要满足这两个条件怎么办?很简单,继承 Binder,然后实现服务接口就行。 编译器为我们生成的类中有一个内部类 public static abstract class Stub extends android.os.Binder implements com.coorchice.coorchicelibone.AIDLDemo 3. Binder需要绑定服务接口,定义DESCRIPTOR描述为了一个Binder和一个特定服务接口绑定,以对外提供功能,需要给Binder定义一个 通常, 4. 实现asInterface()供客户端调用作为一个服务提供者,为了能够给调用者提供远程功能,自然需要能够提供和远程服务关联的 Binder 来通讯,请求服务。获取 Binder 的接口就是 IInterface 中定义的。 先查询一下获取到的和远程 Service 通讯的 Binde 中是否已经添加了功能接口的实现,如果没有则创建代理,通过代理间接的操作 Binder 和远程 Service 通讯,实现功能。 思考:既然我们已经获取到了能够直接和远程 Service 通讯的Binder,为什么不直接操作它去向远程 Service 请求服务呢?确实,我们可以直接操作 Binder 向远程 Service 请求服务,但这过程中有很多繁琐的操作,还有一些 code码的区别,如果不封装隔离的话,随着功能的扩展,我们将很难再去维护这段通讯逻辑。还有就是通过这种方式统一的管理通讯逻辑使得它可以随处使用,而不用没一个要用的地方都去写一遍。 既然是要代理和远程服务通讯,而且通讯的目的是为了请求服务接口定义的功能,那么很自然就能想到去实现服务接口,然后再对应的接口方法中实现逻辑即可。这样就可以分开来维护客户端和服务端的对应的每个功能了。 所以,我们的代理也需要实现服务接口,然后在代理中操作远程通讯的Binder进行通讯。 5. 重写onTransact()在Binder通讯中,一个和远程端通讯的 public boolean transact(int code, Parcel data, Parcel reply, int flags){}
对应的我们在看看 public boolean transact(int code, Parcel data, Parcel reply, int flags){}
可以看出来,两个是成对的操作。 这个过程可以大概抽象成这个样子: 在编译器自动帮我们生成的 第二步. 创建一个远程 Service 我们正常创建一个支持其它应用调用的 Service,Service 怎么创建就不说。主要看看在 Service 最重要的一步,就是继承上面生成的Stub,然后自定义一个 Binder。 接着,在 第三步. 客户端链接Binder 首先重要的一步是,我们必须把这个aidl文件夹拷贝到客户端工程的对应目录下。 包名不能变! 包名不能变! 包名不能变! 然后通过绑定的方式启动这个Service。 总结 恭喜你!现在你已经掌握AIDL了! 实际上,从上面的分析可以看出,AIDL其实就是对Binder机制的简化封装。Android这一套封装使得我们在自己定义Service时方便了许多!你可以不用去编写繁杂的交互,看看编译器自动生成的文件有多不堪入目吧。 但是不管怎么封装,Binder通讯机制的灵魂是不变的,所以要更好的理解这个过程,你可以看看CoorChice的这几篇文章: 《从getSystemService()开始,开撸Binder通讯机制》http://www.jianshu.com/p/1050ce12bc1e; 《能用【白话文】来分析Binder通讯机制?》http://www.jianshu.com/p/fe816777f2cf; 《Binder机制之一次响应的故事》 http://www.jianshu.com/p/4fba927dce05 这几篇文章从我们接触最多的上层入手,一步步分析到了 Binder 内核层,描述了内核的 Bidner 驱动是如何实现一次完整的 c/s 通讯的。 与之相关 日 更 精 彩 微信号:code-xiaosheng 公众号 「code小生」 |
|
来自: codingSmart > 《待分类》