Android AIDL 实现浅析
2016-04-18 22:59
579 查看
最近重温了一遍AIDL,以前只是停留在会用的地步,对于其实现机制不太明白,这次又进行了略微深入的了解,但仍局限在应用层,至于其底层Binder的实现机制并不明白。以后用到在进行更深一步的学习。下面进入正文。
Using AIDL is necessary only if you allow clients from different applications to access your service for IPC and want to handle multithreading in your service.
从系统层面说,Android其实是通过Binder来实现IPC的,AIDL只是帮助我们自动实现了Binder而已。
创建.aidl文件
服务端实现接口
将接口暴露给客户端
客户端像调用本地方法一样调用远程方法
下面结合代码进行详细分析。
编辑完MyAidl.aidl文件后,Eclipse会自动生成名为MyService.java的接口。(AndroidStudio需要手动编译)。下图展示了MyAidl.java的结构:
要想理解AIDL,捋清通过aidl生成的接口很关键。参照上图,MyService继承自IInterface,内部包含一个名为Stub的内部抽象类以及在.aidl文件中定义的各个抽象方法。其中Stub中又包含一个名为Proxy的内部类。Stub与Proxy都实现了MyService接口,Stub还继承了Binder类,Proxy重写了MyService中的抽象方法。大致就是这样。
关键一步。
当service运行在本地进程时,获得本地MyService实现类,调用本地方法。当service运行在remote进程时,返回MyService代理proxy类,调用proxy类中相应方法。 proxy重写MyService中相应方法,并且最终会调用IBinder.transact()方法。经过系统底层(不知道是怎么传递过去的o(╯□╰)o) 该方法传递至remote server 的onTransact()方法。根据多态性质,remote service会调用在service中已经实现的相应方法。
—2016年4月18日23:02:40
—周一
—写于宿舍
什么是AIDL
AIDL是Android Interface Definition Language的简写,即Android接口定义语言。我们知道Android系统为每一个应用开启一个独立的虚拟机,每个应用都运行在各自进程里(默认情况下),彼此之间相互独立,无法共享内存。当一个应用想要访问另一个应用的数据或调用其方法,就要用到Android 系统提供的IPC机制。而AIDL就是Android实现IPC机制的方式之一。除了AIDL,Android还提供了Messenger来实现跨进程通信,不过Messenger是以单线程串行方式(消息队列)来处理来自不同客户端的访问的,并不适合多线程并发访问。当需要提供跨进程以及多线程并发服务时就需要AIDL上场了。谷歌官网如是说:Using AIDL is necessary only if you allow clients from different applications to access your service for IPC and want to handle multithreading in your service.
从系统层面说,Android其实是通过Binder来实现IPC的,AIDL只是帮助我们自动实现了Binder而已。
AIDL实现步骤
AIDL实现主要分为四步:创建.aidl文件
服务端实现接口
将接口暴露给客户端
客户端像调用本地方法一样调用远程方法
下面结合代码进行详细分析。
1. 创建.aidl文件
首先在server端编辑.aidl文件。package com.example.aidl; interface MyService{ int ServiceFunctionA(); int ServiceFunctionB(); int ServiceFunctionC(); }
编辑完MyAidl.aidl文件后,Eclipse会自动生成名为MyService.java的接口。(AndroidStudio需要手动编译)。下图展示了MyAidl.java的结构:
要想理解AIDL,捋清通过aidl生成的接口很关键。参照上图,MyService继承自IInterface,内部包含一个名为Stub的内部抽象类以及在.aidl文件中定义的各个抽象方法。其中Stub中又包含一个名为Proxy的内部类。Stub与Proxy都实现了MyService接口,Stub还继承了Binder类,Proxy重写了MyService中的抽象方法。大致就是这样。
2. 服务端实现接口
所有在MySercie接口中定义的抽象方法都需要被实现,实现方法很简单,只需要继承MyService.Stub类并重写其父类MyService中相应方法即可。获得该类实例并通过Service的onBind()方法返回给客户端。这样客户端在调用bindService()方法时就会收到MyService.Stub类实例,也即Binder。3. 将接口暴露给客户端
客户端通过bindService方式绑定到service时,会在onServiceConnected(ComponentName name, IBinder service)接口处获得来自服务端的Binder类实例。之后通过本地接口方法:myService= MyService.Stub.asInterface(service);
关键一步。
当service运行在本地进程时,获得本地MyService实现类,调用本地方法。当service运行在remote进程时,返回MyService代理proxy类,调用proxy类中相应方法。 proxy重写MyService中相应方法,并且最终会调用IBinder.transact()方法。经过系统底层(不知道是怎么传递过去的o(╯□╰)o) 该方法传递至remote server 的onTransact()方法。根据多态性质,remote service会调用在service中已经实现的相应方法。
4. 客户端调用服务端方法
经过以上步骤后,客户端就可以像调用本地方法一样调用远程方法了。—2016年4月18日23:02:40
—周一
—写于宿舍
相关文章推荐
- Android 虚拟现实(virtual reality)入门指南
- android界面不显示标题栏
- Android Mvp实践
- Android之Dialog详解
- android开发 用线程进行耗时操作,统一处理
- Android基础控件 - ScrollView
- Android群英传笔记——第七章:Android动画机制和使用技巧
- Android群英传笔记——第七章:Android动画机制和使用技巧
- android-----错误解决
- Android之注解的使用——绑定android控件
- Android Volley完全解析
- Android Studio中R文件丢失的解决办法
- Android基础控件 - ProgressBar、SeekBar和RatingBar
- Android双系统之基本问题研究
- 学习笔记(四)ListView
- Android基础控件 - ToggleButton与Switch
- [android] fragment的动态创建
- Android 遇到异常问题
- Android中几种xml解析的比较
- 解决SlidingPaneLayout的滑动冲突