前面已经写了两篇文章介绍了bound service 的两种方式,现在再来说说第三种方式-aidl。

AIDL


Android 远程接口调用语言和其他远程接口调用语言类似。允许你定义 client-servver 的语言接口来满足两者之间的进程通信(IPC)。在 Android 世界里一个进程通常情况下不能正常的访问另一个进程的内存。如果要访问,你需要将对象分解成最原始的数据以便系统能理解并传递对象穿越进程边界。其中实现的代码是复杂的,所以 Android 使用 AIDL 来为你实现。简单的说,aidl 是为了开发者实现跨进程通信提供的一套规则和工具,自动建 基于 Binder 通信的跨进程交换标准模块

注意:基于 aidl 实现的跨进程通信,再多个客户端同时请求 server 服务时,server 的处理是多线程 并发处理的; 而在前面介绍的 Messenger 实现的 boud service 不是多线程处理的,最终其实走的 handler 的方式。

在你开始设计你的AIDL接口之前,你要意识到AIDL接口是直接的方法调用。在哪个线程处理完全取决于调用是来自本地还是远程。具体如下:

*来自本地的调用,执行过程发生在同一个线程里。如果调用发生在UI主线程,则AIDL接口执行也是在主线程。如果调用发生在另一个线程,则AIDL接口的执就在那个线程里。所以如果是本地线程访问service,你完全可以掌控事那个线程在执行(但是这种情况,其实就可以不必使用AIDL了,使用 Binder 获取 service 就行了)。

*调用来自远程进程。如果同时发生多个请求,你无法得知是哪个线程(服务进程中有一个线程池,专门用来处理并发请求的),也就是说AIDL接口必须确保线程安全。
*调用来自远程且实用 oneway关键字,远程调用将不会阻塞,发生transaction data数据之后方法立即返回。如果本地进程调用,oneway关机中无效。

实用AIDL创建bounded service的步骤:


  • 创建一饿.aidl文件

在文件中使用java语法定义接口。

  • 实现接口。

android SDK 工具会根据.aidl文件生产一个java接口,这个接口包含Stub ,Stub继承自Binder并且实现了这个接口。

  • 暴露接口给客户端程序

实现你的 service 并且在你的onBind()方法中返回一个Stub的之类对象。
注意:当你的AIDL接口改变时,确保向前兼容,因为你的AIDL已经向客户端程序发放,确保之前的是可用的。

1 来看看怎么创建.aidl文件
 AIDL使用简单的语法使你能够定义接口。参数支持的类型有
*所有java语言的原始数据类型。
*String
*CharSequence
*List,list的元素必须是AIDL支持的数据类型
*HashMap,元素必须是AIDL支持的数据类型
.aidl文件样例:

// IRemoteService.aidl
package com.example.android;
// Declare any non-de;fault types here with import statements
/** Example service interface */
interface IRemoteService {/** Request the process ID of this service, to do evil things with it. */int getPid();/** Demonstrates some basic types that you can use as parameters* and return values in AIDL.*/void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,double aDouble, String aString);
}

保存到项目src路径下,将自动生成对应的java文件到gen目录下。自动生成的java文件里面有个Stub类,这个类继承Binder且实现了这个接口,其中有几个重要的实现方法asInterface(),asBinder()等。

2 实现接口

实现AIDl文件里面定义的接口,即实现Stub里面的方法。

private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {public int getPid(){return Process.myPid();}public void basicTypes(int anInt, long aLong, boolean aBoolean,float aFloat, double aDouble, String aString) {// Does nothing}
};

mBinder 也就是我们的 service 用来 RPC 的 Binder。

注意:
*调用方不保证来自主线程,你要考虑多线程调用的情况,且确保你的service服务方法是线程安全的。
*如果你知道你使用的服务会耗时,你应该避免在主线程调用。
*不要向调用方抛异常。

3 暴露接口给客户端

你需要通过一个service,在 service 的 onBind()方法中将你的 IRemoteService.Stub 实例返回出去,达到将服务接口暴露给客户端的目的。例如:

public class RemoteService extends Service {@Overridepublic void onCreate() {super.onCreate();}@Overridepublic IBinder onBind(Intent intent) {// Return the interfacereturn mBinder;}private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {public int getPid(){return Process.myPid();}public void basicTypes(int anInt, long aLong, boolean aBoolean,float aFloat, double aDouble, String aString) {// Does nothing}};
}

现在,当客户端(一个activity)调用bindService(),客户端的onServiceConnected()回调方法中将受到一个mBinder实例。客户端为了能调用方法,必须保存一份server端发放的.aidl文件在相同目录下,android 工具也会自动生成一份对应的java文件。 通过YourServiceInterface.Stub.asInterface(mBinder),转化成你所要使用的服务接口的实例。例如:

IRemoteService mIRemoteService;
private ServiceConnection mConnection = new ServiceConnection() {// Called when the connection with the service is establishedpublic void onServiceConnected(ComponentName className, IBinder service) {// Following the example above for an AIDL interface,// this gets an instance of the IRemoteInterface, which we can use to call on the servicemIRemoteService = IRemoteService.Stub.asInterface(service);}// Called when the connection with the service disconnects unexpectedlypublic void onServiceDisconnected(ComponentName className) {Log.e(TAG, "Service has unexpectedly disconnected");mIRemoteService = null;}
};

到此为止,你已经知道怎么使用 aidl 来实现服务接口、客户端怎么获得服务远程代理然后如何调用服务端接口了,后续有时间提供一个 demo。然后再深入研究 Binder 是如何传递数据的、aidl 背后的架构。

boundService-AIDL相关推荐

  1. Android开发之IPC进程间通信-AIDL介绍及实例解析

    一.IPC进程间通信 IPC是进程间通信方法的统称,Linux IPC包括以下方法,Android的进程间通信主要采用是哪些方法呢? 1. 管道(Pipe)及有名管道(named pipe):管道可用 ...

  2. android aidl工具,【Android】AIDL介绍和实例讲解

    前言 为使应用程序之间能够彼此通信,Android提供了IPC (Inter Process Communication,进程间通信)的一种独特实现: AIDL (Android Interface ...

  3. [转] Bound Service的三种方式(Binder、 Messenger、 AIDL)

    首先要明白需要的情景,然后对三种方式进行选择: (一)可以接收Service的信息(获取Service中的方法),但不可以给Service发送信息 (二) 使用Messenger既可以接受Servic ...

  4. Android探索之旅 | AIDL原理和实例讲解

    前言 为使应用程序之间能够彼此通信,Android提供了IPC (Inter Process Communication,进程间通信)的一种独特实现: AIDL (Android Interface ...

  5. Android应用中通过AIDL机制实现进程间的通讯实例

    Android中,每个应用程序都有自己的进程,当需要在不同的进程之间传递对象时,该如何实现呢?显然,Java中是不支持跨进程内存共享的,因此要传递对象,需要把对象解析成操作系统能够理解的数据格式,以达 ...

  6. android AIDL IPC深入分析

    深入分析AIDL原理 博客分类: Android 在上一篇文章(Service使用方式)中,介绍了Android进程间通信(IPC)的使用,并给出了一个示例.但并没有深入分析aidl是怎样可以做到进程 ...

  7. aidl实现进程间通信

    在封装sdk的过程中,sdk是如何与app进行通信的呢? 总所周知,进程间通信,android的四大组件都是可以做到的,如果大家对其中原理有不明白的可以参照http://blog.csdn.net/t ...

  8. android 使用jar里 aidl,Android Studio中用gradle打包带AIDL文件的jar文件

    关键代码task class_jar(type: Jar) { from "build/intermediates/classes/release/" //核心,将.class 文 ...

  9. aidl生成java文件_Android Studio编写AIDL文件后如何实现自动编译生成

    Android Studio编写AIDL文件后如何实现自动编译生成 发布时间:2020-09-17 23:34:54 来源:脚本之家 阅读:111 作者:EdwardChu123 在目录src/mai ...

  10. 在Android工程中加入AIDL文件时,gen目录生成的文件报错-问题解决

    from://http://blog.csdn.net/watt520/article/details/10099047 今天在弄清除缓存的东东,按照网上别人的方法,创建了一个AIDL文件,这个时候发 ...

最新文章

  1. 硅谷理发460!奥巴马前手下发明AI理发机器人,10分钟理发,只收15%费用
  2. 5种流行的Linux发行版:你更喜欢哪一个呢?
  3. CompletableFuture 异步编程
  4. ORACLE常用的一些特殊SQL,收藏收藏,下次需要的时候就不用再翻箱倒柜了
  5. 文件磁盘相关函数[2]-建立新文件 FileCreate
  6. 苹果Mac如何限制进程 CPU 资源占用?
  7. Xshell7免费版申请无需破解
  8. 设计师提高效率必备的10大在线工具
  9. 机器学习、深度学习、计算机视觉、自然语言处理及应用案例
  10. python人民币小写转大写_python人民币小写转大写辅助工具
  11. LAN8720A芯片
  12. FusionCompute集群知识
  13. WCF技术剖析之十四:泛型数据契约和集合数据契约(上篇)
  14. 5G-NR非连续接收DRX参数配置详解
  15. db2 jdbc 连接池_db2 jdbc连接数据库
  16. OpenResty 在马蜂窝广告监测中的应用
  17. Map array 和 array
  18. 【数据库】626. 换座位 -- csae ...when 语句
  19. 从零开始搭建仿抖音短视频App-数据库选型和Navicat数据导入
  20. 简单聊聊MySQL临时表(TEMPORARY TABLE)

热门文章

  1. python语句写入oracle_将Python变量插入Oracle数据库
  2. 地址栏引用PHP中变量,PHP 读取地址栏 参数
  3. java反射取实体字符串_JAVA反射机制 通过反射 Field类获取和修改对象类的字符串值...
  4. bcb quickrep保存为 图片_不容错过的SCI图片处理和组图方法
  5. 利用matlab的帮助功能分别查询inv,MATLAB实验报告第一章..doc
  6. 在Eclipse上安装pydev开发工具
  7. java 我爱你_Java初级教程-课程笔记
  8. android多图片拖动,Android实现图片拖动效果
  9. linux安装oracle tar,在linux as4上用tar方式安装oracle 10g步骤教程-Oracle
  10. 创建的Maven Web工程无法部署到服务器及web-app_2_3.dtd规范