android aidl编译,Android AIDL详解

概述

AIDL是一个缩写,全称是Android Interface Definition Language,也就是Android接口定义语言。是的,首先我们知道的第一点就是:AIDL是一种语言。既然是一种语言,那么相应的就很自然的衍生出了一些问题:

为什么要设计出这么一门语言?

它有哪些语法?

我们应该如何使用它?

PS:在研究AIDL的时候首先需要熟悉service和序列化的一些知识。

为什么要设计这门语言?

AIDL主要是为了实现进程间通信,尤其是在涉及到多进程并发情况下的进程间通信。

我们都知道,安卓中每一个进程都对应一个Dalvik VM实例,都有一块自己独立的内存,都在自己的内存上存储数据,执行自己的操作,各个进程就像海上的小岛,在同一个世界,但又有自己独立的世界。AIDL就相当于两座岛之间的桥梁,我们使用上帝之手,通过AIDL制定一些规则,,规定他们能进行哪些交流——比如在我们定制的规则下他们只能传输一些固定格式的数据。

总之,通过这门语言,我们可以愉快的在一个进程访问另一个进程的数据,甚至调用它的一些方法,当然,只能是特定的方法。

但是,如果仅仅是要进行跨进程通信的话,其实我们还有其他的一些选择,比如 BroadcastReceiver , Messenger 等,但是 BroadcastReceiver 占用的系统资源比较多,如果是频繁的跨进程通信的话显然是不可取的;Messenger 进行跨进程通信时请求队列是同步进行的,无法并发执行,在有些要求多进程的情况下不适用——这种时候就需要使用 AIDL 了。

它有哪些语法?

其实AIDL这门语言非常的简单,基本上它的语法和 Java 是一样的,只是在一些细微处有些许差别——毕竟它只是被创造出来简化Android程序员工作的,太复杂不好。所以我们来总结一下它和java的不同之处:

文件类型:

用AIDL书写的文件的后缀是 .aidl,而不是 .java。

数据类型:

AIDL默认支持一些数据类型,在使用这些数据类型的时候是不需要导包的,但是除了这些类型之外的数据类型,在使用之前必须导包,就算目标文件与当前正在编写的 .aidl 文件在同一个包下——在 Java 中,这种情况是不需要导包的。比如,现在我们编写了两个文件,一个叫做 Book.java ,另一个叫做 BookManager.aidl,它们都在 com.lypeer.aidldemo 包下 ,现在我们需要在 .aidl 文件里使用 Book 对象,那么我们就必须在 .aidl 文件里面写上 import com.lypeer.aidldemo.Book; 哪怕 .java 文件和 .aidl 文件就在一个包下。

AIDL默认支持的数据类型包括:

Java中的八种基本数据类型,包括 byte,short,int,long,float,double,boolean,char。

String 类型。

CharSequence类型。

List类型:List中的所有元素必须是AIDL支持的类型之一,或者是一个其他AIDL生成的接口,或者是定义的parcelable(下文关于这个会有详解)。List可以使用泛型。

Map类型:Map中的所有元素必须是AIDL支持的类型之一,或者是一个其他AIDL生成的接口,或者是定义的parcelable。Map是不支持泛型的。

定向tag:

这是一个极易被忽略的点——这里的“被忽略”指的不是大家都不知道,而是很少人会正确的使用它。在我的理解里,定向 tag 是这样的:AIDL中的定向 tag 表示了在跨进程通信中数据的流向,其中 in 表示数据只能由客户端流向服务端, out 表示数据只能由服务端流向客户端,而 inout 则表示数据可在服务端与客户端之间双向流通。其中,数据流向是针对在客户端中的那个传入方法的对象而言的。in 为定向 tag 的话表现为服务端将会接收到一个那个对象的完整数据,但是客户端的那个对象不会因为服务端对传参的修改而发生变动;out 的话表现为服务端将会接收到那个对象的的空对象,但是在服务端对接收到的空对象有任何修改之后客户端将会同步变动;inout 为定向 tag 的情况下,服务端将会接收到客户端传来对象的完整信息,并且客户端将会同步服务端对该对象的任何变动。

两种AIDL文件:

在我的理解里,所有的AIDL文件大致可以分为两类。一类是用来定义parcelable对象,以供其他AIDL文件使用AIDL中非默认支持的数据类型的。一类是用来定义方法接口,以供系统使用来完成跨进程通信的。可以看到,两类文件都是在“定义”些什么,而不涉及具体的实现,这就是为什么它叫做“Android接口定义语言”。

注:所有的非默认支持数据类型必须通过第一类AIDL文件定义才能被使用。

下面是两个例子,对于常见的AIDL文件都有所涉及:

// Book.aidl

//第一类AIDL文件的例子

//这个文件的作用是引入了一个序列化对象 Book 供其他的AIDL文件使用

//注意:Book.aidl与Book.java的包名应当是一样的

package com.lypeer.ipcclient;

//注意parcelable是小写

parcelable Book;

// BookManager.aidl

//第二类AIDL文件的例子

package com.lypeer.ipcclient;

//导入所需要使用的非默认支持数据类型的包

import com.lypeer.ipcclient.Book;

interface BookManager {

//所有的返回值前都不需要加任何东西,不管是什么数据类型

List getBooks();

Book getBook();

int getBookCount();

//传参时除了Java基本类型以及String,CharSequence之外的类型

//都需要在前面加上定向tag,具体加什么量需而定

void setBookPrice(in Book book , int price)

void setBookName(in Book book , String name)

void addBookIn(in Book book);

void addBookOut(out Book book);

void addBookInout(inout Book book);

}

如何使用AIDL文件来完成跨进程通信?

在进行跨进程通信的时候,在AIDL中定义的方法里包含非默认支持的数据类型与否,我们要进行的操作是不一样的

你可能感兴趣的:(android,aidl编译)