文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

AIDL使用规范及调用过程解析(Android Q)

2022-06-06 14:22

关注

AIDL使用介绍

AIDL的全称是Android Interface definition language,一看就明白,它是一种android内部进程通信接口的描述语言,通过它我们可以定义进程间的通信接口,用处当然就是用来进程间的通信和方法调用了。其实AIDL是Binder的一个上层实现,它简化了Binder的使用,在编译时,由编译器帮助我们完成了大量工作(例如,生成AIDL文件所对应的.java类)。

先介绍一下AIDL进程间通信的流程。

AIDL通信流程简介 1. AIDL接口的创建

AIDL文件中,并不是所有的数据类型都是可以使用的,它支持的数据类型有:

基本数据类型(int,long,char,boolean,double等) String和CharSequence List:只支持ArrayList,而且list中的元素也必须是 AIDL 支持的类型 Map:只支持HashMap,里面的key和value也必须是AIDL支持的类型 Parceable:所有实现了 Parceable 接口的对象 AIDL:所有的 AIDL 接口本身也可以在 AIDL 文件中使用,所以 IBinder 类型也是支持的 2. 服务端

服务端首先要创建一个 Service 用来监听客户端的请求,然后将在对应AIDL文件中声明的接口实现,并且通过onbind函数返回相应 IBinder 对象即可。

3. 客户端

客户端所要做的事情就稍微简单一些,首先需要绑定服务端的Service,绑定成功后,将服务端返回的 IBinder 对象转成AIDL接口所属的类型,接着就可以调用AIDL中的方法了。

AIDL文件及参数说明 自定义类型

通常,AIDL默认支持基础类型参数及返回值的数据传递。如果AIDL文件中用到了自定义的Parcelable对象,那么必须新建一个和它同名的AIDL文件,并在其中声明它为Parcelable类型。

例如,我们定义了一个名为RequestData的数据类型,要想在AIDL中使用它,除了它自己的RequestData.java文件之外,我们还必须定义一个名为RequestData.aidl的文件(包名必须和RequestData.java中的相同),内容如下:

package com.testaidl;
parcelable RequestData;
参数标志

AIDL中除了基本数据类型,其他类型的参数必须标上方向:in,out或者inout, in表示输入型参数,out表示输出型参数,inout表示输入输出型参数。

我们要根据实际需要去指定参数类型,不能一概使用out或者inout,因为这在底层实现是有开销的。

接口及同步

AIDL接口中只支持方法,不支持声明静态常量,这一点区别于传统的接口。

客户端调用服务端方法,被调用的方法运行在服务端的Binder线程池中,同时客户端线程会被挂起,这个时候如果服务端方法执行比较耗时,就会导致客户端线程长时间阻塞,而如果这个客户端线程是UI线程的话,就会导致客户端ANR,所以如果知道服务端的一个方法是耗时的,就要避免在客户端的UI线程中去调用该远程方法。

但是有一种方法可以发起非阻塞式的远程调用:就是在声明AIDL时,加上oneway关键字。

相比平常自定义的 aidl,多了 oneway 的关键字,声明和不声明 oneway 关键字的在于生成 Java 类中一个参数:
在这里插入图片描述在这里插入图片描述
不声明 oneway 时,mRemote.transact 传入的最后一个参数是 0;声明 oneway 时,mRemote.transact 传入的最后一个参数是 android.os.IBinder.FLAG_ONEWAY 。

FLAG_ONEWAY 的作用就是让客户端能够非阻塞的调用远程方法。

系统Service的调用示例

我们以系统服务的调用来分析AIDL的使用过程。

系统服务的调用过程

首先通过 ServiceManager.getService()方法获取一个IBinder对象,但是这个IBinder对象不能直接调用,必须要通过asInterface方法转成对应的IInterface对象才可以使用,如果在同一个进程中(当然,这是跨进程通信,这种情况很少),就会直接返回通过attachInterface方法设置的IInterface对象(上面代码所述),但是如果不是在同一个进程中,就会先通过IBinder对象创建一个Proxy对象(服务的本地代理对象),然后在Proxy对象中通过调用IBinder对象的transact方法调用到服务进程的Service中,实现了跨进程的通信。

以AMS为例,我们来看具体实现。

AMS的服务调用关键实现

AIDL 文件生成的类中会自动生成两个类,Proxy 类和 Stub 类,对应的是 ActivityManagerProxy 和 ActivityManagerService 类。

我们使用ActivityManager实现AMS通信时,在其内部都是调用ActivityManagerNative来实现的。我们来看相关类的继承关系:
原创文章 13获赞 0访问量 3969 关注 私信 展开阅读全文
作者:卜大爷


阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯