1 AIDL简介

AIDL(Android 接口定义语言),可以使用它定义客户端与服务端进程间通信(IPC)的编程接口。在

Android系统中,每个进程都运行在一块独立的内存中,在其中完成自己的各项活动,与其他进程都分 隔开来。可是有时候我们又有应用间进行互动的需求,比较传递数据或者任务委托等, AIDL就是为了满 足这种需求而诞生的。通过AIDL,可以在一个进程中获取另一个进程的数据和调用其暴露出来的方法, 从而满足进程间通信的需求。

AIDL是用于定义服务端和客户端通信接口的一种描述语言,可以拿来生产IPC代码,从某种意义上说

AIDL其实就是一个模板,因为在使用过程中,实际起作用的并不是AIDL文件,而是据此生产的一个

Interface的实例代码, AIDL其实是为了避免我们重复写代码而出现的一个模板。

2,为什么要设计这门语言?

设计这门语言的目的是为了实现进程间通信,尤其是在涉及多进程并发情况下的进程间通信

3,它有哪些语法?

其实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 文件就在一个包下。
默认支持的数据类型包括:

Java中的八种基本数据类型,包括 byte,short,int,long,float,double,boolean,char。
String 类型。
CharSequence类型。
List类型:List中的所有元素必须是AIDL支持的类型之一,或者是一个其他AIDL生成的接口,或者是定义的parcelable(下文关于这个会有详解)。List可以使用泛型。
Map类型:Map中的所有元素必须是AIDL支持的类型之一,或者是一个其他AIDL生成的接口,或者是定义的parcelable。Map是不支持泛型的。

4. 使用流程

1 . 在 .aidl 文件中定义 AIDL 接口,并将其添加到应用工程的 src 目录下,创建完成之后 rebuild 2. Android SDK 工具会自动生成基于该 .aidl 文件的 IBinder 接口,具体的业务对象实现这个接口, 这个具体的业务对象也是 IBinder 对象,当绑定服务的时候会根据实际情况返回具体的通信对象 (本地还是代理)

3. 将客户端绑定到该服务上,之后就可以调用 IBinder 中的方法来进行进程间通信(IPC)

4.1下面从几个方面介绍AIDL的使用

1 . 创建.aildl 文件

2. 具体的业务对象实现基于 .aidl 文件生成的接口

3. 向客户端公开接口

4. 客户端远程调用

5. 验证 AIDL

4.1.1 创建.aildl 文件

在 AIDL 中可以通过可带参数以及返回值的一个或多个方法来声明接口,参数和返回值可以是任意类 型, AIDL 中支持的数据类型如下:

java 的 8 种数据类型: byte、 short、 int、 long、 float、 double、 boolean、 char

除此之外支持 String、 charSequence、 List、 Map

自定义数据类型 如果参数或返回值类型为 List 或 Map 时:

List 中的所有元素都必须是 AIDL 支持的数据类型、其他 AIDL 生成的接口或自己声明的可打包类 型。可选择将 List 用作“通用”类(例如, List)。另一端实际接收的具体类始终是 ArrayList,但生 成的方法使用的是 List 接口。

Map 中的所有元素都必须是 AIDL 支持的数据类型、其他 AIDL 生成的接口或您声明的可打包类 型。 不支持通用 Map(如 Map 形式的 Map)。 另一端实际接收的具体类始终 是 HashMap,但生成的方法使用的是 Map 接口。

4.1.2 具体的业务对象实现基于 .aidl 文件生成的接口

1.首先,在工程的 src 目录下创建 .aidl 文件,具体如下图所示:

2.打开IPersonAidlInterface.aidl,在 .aidl 文件中添加具体的业务方法,文件内容如下:

package com . manu . aidl demo ;// Declare any non-default types here with import statementsinterface IPersonAi dlInterface {//具体的业务void setName (String name) ;void setAge (int age) ;String getInfo () ;/*** Demonst rates some basic types that you can use as paramete rs* and return values in AIDL .*/void basicTypes (int anInt , long aLong , boolean aBoolean , float aFloat , double aDouble , String aString) ;
}

3.然后,重新 rebuild project , Android SDK 工具会在相应的目录生成对应的与 .aidl 文件同名的 .java

接口文件,具体目录如下:

4. 那么这个业务要体现在什么地方呢,从上面可知 Stub 是一个抽象类,那么它所提供的具体业务必 然需要一个具体的实现类来完成,下面实现这个具体的业务类,具体如下:

public class IPersonImpl extends IPersonAi dlInterface . Stub {private String name ;private int age ;@Overridepublic void setName (String name) throws RemoteExcepti on {this . name = name ;}@Overridepublic void setAge (int age) throws RemoteExcepti on {this . age = age ;}@Overridepublic String getInfo () throws RemoteExcepti on {return "My name is "+name+" , age is "+age+" ! " ;}@Overridepublic void basi cTypes (int anInt , long aLong , boolean aBoolean , float aFloat , double aDouble , String aString) throws RemoteExcepti on {}
}

3.3.3 向客户端公开接口

创建一个 Service 以便对外提供具体的业务,具体如下:

// Servicepublic class PersonSe rvice extends Service {publicPe rsonService () {}@Overridepublic IBinder onBind (Intent intent) {return new IPersonImpl () ;}
}

当外部调用 bindService() 方法绑定服务时,就会调用 onBind() 方法返回 IBinder 对象,这个 IBinder

对象也是具体的业务对象,如这里的 onBind() 方法返回的也是具体的业务对象,两者是统一的。此外, 创建的 Service 要在 AndroidManifest.xml 文件中声明,具体如下:

serviceandroid : name=" . PersonService"android : enabled="true"android : exported="true"android : process=" : remote">
</service>

其中使用 process 关键字表示为该服务开启一个独立的进程, remote 可任意,表示进程名称, ":"将会 在主进程(进程名为包名)添加新名称作为新进程的名称,如 com.hopu.study 将会变成

com.hopu.study:remote。

4.1.3 客户端远程调用

通过上面几步完成了服务的搭建,并将服务运行在独立进程中,下面主要就是客户端的具体调用了,具 体实现参考如下:

public class MainActivity extends AppCompatActi vity {private Button btn_start_service , btn_stop_service , btn_call _remote ;private static final String TAG = "MainActivity" ;private IPrsonAidl Interface iPersonAi dlInterface ;@Overrideprotected void onCreate (Bundl e savedInstanceState) {super . onCreate (savedInstanceState) ;setContentView(R . layout . activity_main) ;btn_start_service = findViewById (R . i d . btn_start_service) ;btn_stop_se rvi ce = fi ndVi ewById (R.id.btn_stop_service) ;btn_cal l _remote = findViewById (R . id . btn_call _remote) ;btn_start_servi ce . setOnClickListener (new View . OnClickListene r () {@Overridepublic void onClick(Vi ew v) {bindService Click(v) ;}       }) ;btn_stop_servi e . setOnClickListener (new Vi ew . OnCl i ckLi stene r () {@Overridepublic void onClick(View v) {unbindSe rviceClick(v) ;}}) ;btn_call _remote . setOnClick Listener (new View . OnClick Listener () {@Overr depublic void onClick(View v) {call RemoteClick(v) ;}}) ;}public void bindService Cick(View view) {Log . i (TAG , "绑定服务 . . . ") ;Intent intent = new Intent (this , PersonSe rvice . class) ;// 绑定服务时自动创建服务bindService (intent , conn , Context . BIND_AUTO_CREATE) ;}public void unbindSe rviceCl i ck(View view) {Log . i (TAG , "解绑服务 . . . ") ;unbindService (conn) ;}public void call RemoteClick(View view) {Log . i (TAG , "远程调用具体服务 . . . ") ;try {iPersonAidl Interface . setName ("Tom") ;iPersonAidl Interface . setAge (10) ;String info = iPersonAidl Interface . getInfo () ;System . out . println ("这是远程调用的服务信息: "+info) ;} catch (RemoteExcepti on e) {e . printStackTrace () ;}}private Servi ceConnection conn = new Service Connection () {@Overridepublic void onService Connected (ComponentName name , IBinde rservice) {// 根据实际情况返回 IBinder 的本地对象或其代理对象iPersonAidl Interface = IPersonAidl Interface . Stub . asInterface (service) ;System . out . println ("具体的业务对象: "+iPersonAi dlInterface) ;}@Overridepublic void onService Disconnected (ComponentName name) {// Service 意外中断时调用
}};

4.1.4 验证 AIDL

通过前面几步,服务端与客户端已经完成,下面来验证能否调用具体的业务,这里分两种情况:

1、相同进程 创建 Service 的时候不要在 AndroidManifest.xml 文件中不要使用 process 开启独立进程即可,此时服 务进程默认与客户端属于统一进程,结果如下:

2、不同进程 显然,如果服务与客户端处于不同进程,也就是常常说的进程间通信,具体是由 IBinder 对象的代理对 象完成,反之,使用本地对象,也就是本地的 IBinder 对象,具体就是实现 AIDL 的业务类所生成的对象

AIDL 简介以及使用相关推荐

  1. Android的IPC机制(一)——AIDL的使用

    综述 IPC(interprocess communication)是指进程间通信,也就是在两个进程间进行数据交互.不同的操作系统都有他们自己的一套IPC机制.例如在Linux操作系统中可以通过管道. ...

  2. xamarin学习笔记A19(安卓AIDL)

    (每次学习一点xamarin就做个学习笔记和视频来加深记忆巩固知识) 如有不正确的地方,请帮我指正. AIDL简介   AIDL(Android Interface Definition Langua ...

  3. android aidl空指针,AIDL使用笔记

    最近这段时间在项目开发中使用到了AIDL,之前对这块的内容比较陌生.所以特地分享一下关于AIDL的一些使用知识,如果有什么写的不对的地方还请指出.这里先谢谢了!!! 本文知识点: AIDL简介 AID ...

  4. android应用开发全程实录出版

    这本书经历了大半年的时间,终于可以和读者见面了.书籍由我和微度网http://www.microdu.com/其他两位资深开发者共同完成. 最近经历了很多,应该是人生的一个转折点吧.总会有一些选择,将 ...

  5. Android 跨进程通信大总结

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/111553746 本文出自[赵彦军的博客] 文章目录 1.Android进程 2.修 ...

  6. 操龙兵:非独立同分布学习

    原文地址:非独立同分布 AIDL简介 "人工智能前沿讲习班"(AIDL)由中国人工智能学会主办,旨在短时间内集中学习某一领域的基础理论.最新进展和落地方向,并促进产.学.研相关从业 ...

  7. Android 4.0按键事件以及系统流程分析

    Android 4.0中按键的处理流程 按键在Android系统中,有着不同的代表意义.以前的全键盘的手机代码没有阅读过,所以也不是很了解.本人介绍的是在触摸屏的手机上的按键消息的处理流程. 在现在触 ...

  8. Ninja简介-Android10.0编译系统(九)

    摘要:Ninja具体干了什么? 阅读本文大约需要花费16分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Android的平台设计,欢迎关注我,谢谢! 欢迎关注我的公众 ...

  9. Blueprint简介-Android10.0编译系统(六)

    摘要:Android.bp由Blueprint进行解析翻译,最终通过soong build编译成ninja文件,那么Blueprint是什么呢? 阅读本文大约需要花费10分钟. 文章首发微信公众号:I ...

最新文章

  1. 如何读取比机器内存大的文件(内存4G,文件 8G,读取大文件) ?
  2. [lua]判断nginx收到的是否json
  3. php安装redis扩展详细步骤 不会可以加QQ
  4. Python--day46--MySQL视图
  5. 第五课 路由之初识路由
  6. 《剑指Offer》62:圆圈中最后剩下的数字(约瑟夫环)
  7. [线段树][树上差分] Jzoj P3397 雨天的尾巴
  8. qt利用QSplitter任意拆分窗口
  9. Mysql drop table 原理_mysql事务的实现原理
  10. Android基础(四) Fragment Part 1
  11. “630”落幕 光伏何去何从?
  12. 小程序 房租水电费记录管理_智慧物业管理小程序怎么开发?
  13. 最少承诺原则和单一职责原则_单一责任原则
  14. oracle数据库表空间容量查询及扩容
  15. 极限与连续知识点总结_大一上学期《高等数学》知识整理-第一章 极限与连续...
  16. java clh_【Java】CLH 自旋锁
  17. 目录服务器的互联网标准协议,2014年4月自学考试《互联网及其应用》试题
  18. 【无标题】asdas
  19. 网络游戏外挂制作(3)-1
  20. 基于校园生活一体化管理系统的需求分析

热门文章

  1. [导入][幻想情侣][2008热播韩剧][全16集+OST][韩语中字]
  2. mysql 字符串转日期及其他日期转换
  3. show slave status
  4. 【vs】开始运行、开始运行不调试区别
  5. sed基本用法介绍1
  6. Cas乐观锁的初步理解
  7. EasyX中使用背景音乐
  8. 网易云音乐HTML5随机音乐播放器源码
  9. WIN10搭建深度学习环境 GTX1080+CUDA9.0+cuDNN7.0+Python3.6+Tensorflow1.6.0
  10. 置换贴图(Displacement map),凹凸贴图(Bump map)与法线贴图(Normal map)的区别