客户端和服务端之间实现进程间通信
1.只有当你需要来自不同应用的客户端通过IPC通信来访问你的服务时,并且想在服务里处理多线程的业务,这时就需要使用AIDL。
2.如果你不需要同时对几个应用进程IPC操作,你最好通过实现Binder接口来创建你的接口。
3.如果你仍需要执行IPC操作,但不需要处理多线程,使用Messenger来实现接口即可。
4.无论如何,在实现AIDL之前确保你完全理解Bound Service相关知识。
创建提供绑定的服务时,您必须提供 IBinder,用以提供客户端用来与服务进行交互的编程接口。 您可以通过三种方法定义接口:
扩展 Binder 类
如果服务是供您的自有应用专用,并且在与客户端相同的进程中运行(常见情况),则应通过扩展Binder 类并从 onBind() 返回它的一个实例来创建接口。客户端收到 Binder 后,可利用它直接访问 Binder 实现中乃至 Service 中可用的公共方法。
如果服务只是您的自有应用的后台工作线程,则优先采用这种方法。 不以这种方式创建接口的唯一原因是,您的服务被其他应用或不同的进程占用。
使用 Messenger
如需让接口跨不同的进程工作,则可使用 Messenger 为服务创建接口。服务可以这种方式定义对应于不同类型 Message 对象的 Handler。此 Handler 是 Messenger 的基础,后者随后可与客户端分享一个 IBinder,从而让客户端能利用 Message 对象向服务发送命令。此外,客户端还可定义自有Messenger,以便服务回传消息。
这是执行进程间通信 (IPC) 的最简单方法,因为 Messenger 会在单一线程中创建包含所有请求的队列,这样您就不必对服务进行线程安全设计。
使用 AIDL
AIDL(Android 接口定义语言)执行所有将对象分解成原语的工作,操作系统可以识别这些原语并将它们编组到各进程中,以执行 IPC。 之前采用 Messenger 的方法实际上是以 AIDL 作为其底层结构。 如上所述,Messenger 会在单一线程中创建包含所有客户端请求的队列,以便服务一次接收一个请求。 不过,如果您想让服务同时处理多个请求,则可直接使用 AIDL。 在此情况下,您的服务必须具备多线程处理能力,并采用线程安全式设计。
如需直接使用 AIDL,您必须创建一个定义编程接口的 .aidl 文件。Android SDK 工具利用该文件生成一个实现接口并处理 IPC 的抽象类,您随后可在服务内对其进行扩展。
注:大多数应用“都不会”使用 AIDL 来创建绑定服务,因为它可能要求具备多线程处理能力,并可能导致实现的复杂性增加。因此,AIDL 并不适合大多数应用,本文也不会阐述如何将其用于您的服务。如果您确定自己需要直接使用 AIDL,请参阅 AIDL 文档。