AIDL知识

作者: 农民工Alan | 来源:发表于2016-04-14 15:33 被阅读247次

前言

本文翻译自(http://developer.android.com/intl/zh-cn/guide/components/aidl.html#Defining),并结合网上看到的一些信息整理而成。

一、AIDL概述

AIDL与其他你曾使用的IDL语言类似。它允许你定义客户端与服务端达成一致的程序接口来进行进程间通信(IPC)。在安卓系统中,一个进程不能正常访问另一个进程的内存。所以,他们需要将对象分解成操作系统可以理解的原始类型,与马歇尔对象跨越边界的你。代码做编组是沉闷,所以Android处理你的AIDL

注意:如果你只允许来自不同应用程序的客户端IPC访问你的服务和要处理的多线程服务你使用AIDL是必要的。如果你不需要执行不同的应用程序之间的并发IPC,你应该通过实施粘合剂或创建你的界面,如果你想执行IPC,但不需要处理多线程,实现你的接口使用一个信使。不管怎样,要确保你了解绑定服务在实施中。

在你开始设计你的AIDL接口,注意,调用AIDL接口直接调用的函数。你不应该对调用发生的线程做假设。所发生的不同取决于调用是从本地进程或远程进程中的线程的。具体:

*本地进程中的调用是在同一个线程中执行的。如果这是你的主UI线程,该线程在AIDL接口中继续执行。如果是另一个线程,那就是在服务中执行你的代码的那个。因此,如果只有本地线程访问服务,你可以完全控制线程执行它(如果是这样的话,那么你不应该这样,而应该通过使用AIDL实现粘合剂创建接口)。

*来自远程进程的呼叫从一个线程池中被调度,该平台保持在您自己的进程中。您必须为来自未知线程的传入呼叫准备,同时在同一时间发生多个呼叫。换句话说,AIDL接口的一个实现必须完全线程安全。

单向的关键词修改远程调用的行为。使用时,远程调用不块;它只发送事务数据并立即返回。该接口的实现最终接收这从 [胶]定期拜访(http://developer.android.com/reference/android/os/binder.html
线程池作为一个正常的远程调用。如果 单向
使用本地电话,没有影响,电话仍然是同步的。

二、定义AIDL接口

使用java语言的语法定义一个.aidl文件,保存到服务所在应用和绑定者所在应用的src/目录下面。(.aidl 文件中写客户端所需要调用的接口)

当你创建的每个应用程序包含.aidl文件后,Android SDK工具基于.aidl文件生成一个IBinder接口。服务端必须实现IBinder接口,这时客户端可以绑定到服务并从IBinder调用方法来执行IPC(执行clean即可生成)

使用AIDL创建一个bounded service,遵循以下步骤:
1.创建.aidl文件
该文件定义了方法签名的编程接口
2.实现接口
Android SDK工具基于.aidl文件生成Java语言的接口。该接口有一个内部抽象类命名为Stub,该类继承于Binder并实现了AIDL接口中方法。你必须扩展Stub类并实现方法。
3.暴露接口给客户端
实现Service并重写onBind() 来返回Stub类的实现

注意:为了避免破坏其他应用使用你的service,AIDL接口中的任何改变必须保持向后兼容性。你的.aidl文件必须拷贝到访问你的服务接口的应用,且保持原来接口的支持。

1.Create the .aidl file
AIDL使用简单的语法声明一个或者多个带有参数和返回值的方法。参数和返回值可以是任何类型,甚至是其他AIDL生成的接口。
你必须使用Java编程语言构建.aidl文件,每一个.aidl文件必须定义一个接口,且只需要接口声明和方法签名。

默认情况下,AIDL支持下列数据类型:
*Java编程语言中的所有基本类型(如 int,long, char, boolean 等)
*String
*CharSequence
*List
List中的所有元素必须是一个支持的数据类型,或AIDL生成的接口或者声明的parcelables。一个List可以用作一个通用类(例如,List<String>)。虽然使用的是List接口,实际对方使用的通常是ArrayList。
*Map
Map中的所有元素必须是一个支持的数据类型,或AIDL生成的接口或者声明的parcelables。一般通用Map(例如,Map<String,Integer>不支持)。虽然使用的是Map接口,实际对方使用的通常是HashMap。

不在上述类型中的附加类型,即使作为接口定义在相同的包中,也需要import声明。

在定义服务接口时,请注意:
*方法可以有零个或多个参数,并返回一个值或空
*所有非基本数据参数都需要一个方向性tag指示数据的方式。要么in,out或者inout(看如下例子)
基础数据类型默认是in,并且不能是其他的
*除了导入包前面的注释,其他的.aidl文件中的代码注释都会包含在生成的IBinder接口文件中
*AIDL中只有方法是支持的,你不能定义静态字段

下面是个.aidl文件的例子


Paste_Image.png

构建应用时,保存 .aidl文件到src目录下,SDK工具会在gen目录下自动生成与.aidl文件相匹配的.java 文件(例如,IRemoteService.aidl生成IRemoteService.java)

2.实现接口
当你构建一个应用的时候,Android SDK工具生成一个以.aidl文件名命名的java接口文件。生成的接口包含一个Stub子类,该类是父类的抽象实现,并且声明了.aidl中所有的方法。
注:Stub也定义了一些辅助方法,值得注意的是asInterface(),它使用一个IBinder(通常传给客户端的onServiceConnected()的回调方法)并返回一个Stub接口实例。更多细节请看调用IPC方法部分。

Paste_Image.png

3.暴露接口给客户端

Paste_Image.png Paste_Image.png Paste_Image.png Paste_Image.png Paste_Image.png Paste_Image.png

相关文章

网友评论

    本文标题:AIDL知识

    本文链接:https://www.haomeiwen.com/subject/qbqglttx.html