- 浏览: 1075943 次
- 性别:
- 来自: 苏州
文章分类
- 全部博客 (202)
- Android (31)
- Eclipse 使用 (14)
- 笔记 (5)
- 杂七杂八 (3)
- Java (18)
- 数据库 (6)
- web (21)
- JavaScript (24)
- Http (1)
- 杂谈 (1)
- JSP & Servlet (5)
- log4j (1)
- Linux (13)
- MS Office (3)
- postgresql (7)
- Tomcat (5)
- windows (4)
- tmp (1)
- Perl (1)
- Struts2 (17)
- JQuery (5)
- HTML5 (3)
- JSLint (2)
- iphone (1)
- ant (2)
- IE (1)
- tcp (1)
- JBoss (4)
- 正则表达式 (2)
- jmeter (1)
- CI (1)
- sonarqube (1)
- junit (1)
- chrome (1)
- mybatis (2)
- mysql (3)
- spring (2)
- maven (1)
最新评论
-
天使建站:
看这里:jquery里和操作数组的相关的:$.merg ...
JQuery 数组 -
lgywindows:
我照你的方法实现了在java中取国际化。谢谢提供!
spring mvc中,如何在 Java 代码里,获取 国际化 内容 -
ylhkaixin:
请教下大神,我转换报告的时候报错:report: [x ...
通过ant来批量执行jmeter脚本,并生成报告(附: 生成报告时报“Content is not allowed in prolog”这个错误的解决方案) -
lemon_yt:
正在找
spring mvc中,如何在 Java 代码里,获取 国际化 内容 -
Rainbow702:
alike222 写道Rainbow702 写道MyDream ...
通过ant来批量执行jmeter脚本,并生成报告(附: 生成报告时报“Content is not allowed in prolog”这个错误的解决方案)
前面写了 Bind Service 的两种实现方式,接下来转一篇贴子来简述一下最后一种实现方式
第三种:使用 AIDL
前面讲的使用 Messenger 技术,其实是基于 AIDL架构的,但是 Messenger 使用一个队列来处理所有的请求,这样一来,就无法进行多线程的并发了。所以,如果你想同时接受并处理多个 client 的请求,那么请使用 AIDL 来实现,但这样的话,你需要小心地进行同步处理了哦~
默认情况下,一个应用不管有多少个 Activity、Service 或其他组件,它们都是运行在一个进程上,但是我们可以安排 Service 运行一个新的进程上,但是不同进程之间应该如何通信呢?当需要在不同的进程之间传递对象时,应该怎么做呢?AIDL(Android Interface Definition Language) 便是解决这一问题的钥匙。
使用 AIDL 并不是难事,但是比较繁琐,并且一不小心容易出错。好在 Android Dev Guide 的 "AIDL" 章节(在 "Dev Guide " 左侧列表的最下面)对这个问题讲解非常详细,再结合 Android APIDemo 中的 Remote Service Binding 给出了的示例,这都给了开发者提供了非常到位的帮助。以下内容就是我结合二者,整理出来的笔记,力求真理,但能力有限,差错难免,请读者坚持自己的判断力,本文只供参考,且不可尽信。
一、使用 AIDL 实现 IPC
面对问题,应统揽全局,归纳阶段,划定步骤,共得出四大步,分列如下:
① 创建.aidl 文件
在这个文件里定义 method 和 field
② 把 .aidl 文件加入到 makefile 中去
如果使用 Eclipse 则 ADT 会帮你管理
③ 实现接口方法
AIDL 编译器会根据接口生成一个用 Java 语言编写的interface,这个 interface 有一个抽象的内部类,名字为 Stub,你必须创建一个类,继承于它,并且实现 .adil 文件中所声明的方法
④ 公开接口给客户端
如果创建的是 service,则应该继承自 Service,并且重载 Service.onBind() 返回实现接口的类的实例
这四个步骤在 Remote Service Binding 中均有所呈现,以下分开阐述。Remote Service Binding 共包含有两个 .java 文件,三个 .aidl 文件,物理结构比较简单,但是逻辑结构就不那么简单,以下用 Class Diagram 来展示其中的关系。
1、创建.aidl 文件
AIDL 语法简单,用来声明接口,其中的方法接收参数和返回值,但是参数和返回值的类型是有约束的,且有些类型是需要 import,另外一些则无需这样做。
AIDL 支持的数据类型划分为四类,第一类是 Java 编程语言中的基本类型,第二类包括 String、List、Map 和 CharSequence,第三类是其他 AIDL 生成的 interface,第四类是实现了 Parcelable 接口的自定义类。
其中,除了第一类外,其他三类在使用时均需要特别小心。
使用第二类时,首先需要明白这些类不需要 import,是内嵌的。其次注意在使用 List 和 Map 此二者容器类时,需注意其元素必须得是 AIDL 支持的数据类型,List 可支持泛型,但是 Map 不支持,同时另外一端负责接收的具体的类里则必须是 ArrayList 和 HashMap。
使用第三、四类时,需要留意它们都是需要 import 的,但是前者传递时,传递的是 reference,而后者则是 value。
在创建 .aidl 文件的过程中,应该注意一旦 method 有参数,则需注意在前面加上 in, out 或 inout,它们被称为 directional tag,但是对于基本类型的参数,默认就是 in,并且不能为其他值。
Remote Service Binding 共包括了三个 .aidl 文件,分别是IRemoteService.aidl、IRemoteServiceCallback.aidl、ISecondary.aidl,通过它们可以看到如何使用第一类和第三类的数据类型,稀罕的是,看不到第二类、第四类数据类型的使用,也没有看到 directional tag。
2、实现 Interface
AIDL 为你生成一个 interface 文件,文件名称和 .aidl 文件相同。如果使用 Eclipse 插件,则 AIDL 会在构建过程中自动运行,如果不使用插件,则需要先使用 AIDL。
生成的 interface 会包含一个抽象内部类 Stub,它声明了在 .aidl 文件里的所有方法。要想实现你在 .aidl 文件里定义的接口,就必须实现这个Stub类,如下:
/** * This implementation is used to receive callbacks from the remote * service. */ private IRemoteServiceCallback mCallback = new IRemoteServiceCallback.Stub() { /** * This is called by the remote service regularly to tell us about * new values. Note that IPC calls are dispatched through a thread * pool running in each process, so the code executing here will * NOT be running in our main thread like most other things -- so, * to update the UI, we need to use a Handler to hop over there. */ public void valueChanged(int value) { mHandler.sendMessage(mHandler.obtainMessage(BUMP_MSG, value, 0)); } };
Stub 也定义了一些帮助方法,比较常用的有 asInterface(),其接收一个 IBinder 作为参数,并且返回一个 interface 的实例用来调用IPC方法。
private static INotificationManager sService; static private INotificationManager getService() { if (sService != null) { return sService; } sService = INotificationManager.Stub.asInterface(ServiceManager.getService("notification")); return sService; }
要实现 interface,需要继承 Stub,实现其方法,这在 RemoteService 和 RemoteServiceBinding 都可以找到相关代码。
这个环节是重中之重,需要特别小心的有两点,其一是抛出的所有异常均不会发给调用者;其二是IPC调用是同步的,这意味IPC服务一旦花费较长时间完成的话,就会引起ANR,应该将这样的操作放在单独的线程里。
3、向客户端公开 Interface
独乐乐不如众乐乐,需要将服务公开出去,要达成这个目的,须得创建一个 Service 的子类,并且实现 Service.onBind(Intent),通过这个方法将实现了接口的类的实例返回回来。通过查看 RemoteService 一目了然。
@Override public IBinder onBind(Intent intent) { // Select the interface to return. If your service only implements // a single interface, you can just return it here without checking // the Intent. if (IRemoteService.class.getName().equals(intent.getAction())) { return mBinder; } if (ISecondary.class.getName().equals(intent.getAction())) { return mSecondaryBinder; } return null; }
其中的 mBinder 和 mSecondaryBinder 分别是实现了 IRemoteService 和 ISecondary 接口的类的实例。
4、使用Parcelables传值
前文中提到 Remote Servcie Binding 没有使用第四类数据类型作为参数,这是示例的不足,要想让一个类变成第四类,需要遵照以下步骤:
① 引入 Parcelable 接口
② 实现 writeToParcel(Parcel out)
③ 增加一个静态的field,其实现 Parcelable.Creator 接口
④ 创建一个 .aidl 文件,用以声明你的 parcelables 类
在 "AIDL" 中,类 Rect 是一个不错的示例,弥补了 Remote Service Binding 的不足。
二、调用 IPC 方法
万事俱备,只欠东风,IPC 备妥,只待调用。在 Remote Service Binding 中,RemoteServiceBinding 正是 IPC 的调用者,既然要使用接口,那就先声明 interface 类型的变量
// The primary interface we will be calling on the service. IRemoteService mService = null; // Another interface we use on the service. ISecondary mSecondaryService = null;
实现 ServiceConnection,在 onServiceConnected(ComponentName className, IBinder service) 中完成对 mService 和 mSecondaryService 的赋值。
private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { mService = IRemoteService.Stub.asInterface(service); // ... 以下省略 } }
接着别忘了调用 Context.bindService(),完成任务以后,调用 Context.unbindService()。如果在 connection 中断的情况下,调用 IPC 方法,你会遇到 DeadObjectException,这是 remote method 能抛出的唯一异常。
原文地址: http://www.poemcode.net/2010/05/aidl-ipc/
发表评论
-
动态更新APK
2011-09-08 12:29 4336开发了一个APK后,往往后续需要进行更新升级。那么,当用户选择 ... -
Android数据保存之PreferenceActivity
2011-09-07 15:49 5741看到很多书中都没有对PreferenceActivit ... -
AsyncTask 的使用
2011-08-22 13:39 6019在开发Android应用时必须遵守单线程模型的原则: ... -
Android Service 之三(Bind Service,使用 Messenger)
2011-08-15 17:26 10019上次讲了第一种 Bind Service 的实现方式,今天讲 ... -
Android NOtification 使用
2011-08-12 17:12 4994一、 Notification 简介 在 andro ... -
如何快速启动 Android 模拟器
2011-08-12 11:04 2491一直不知道在创建 AVD 时,那个 "enable ... -
Android 模拟器启动失败(SDL_app:emulator.exe )解决方法
2011-08-12 10:45 3530今天新建了一个AVD,给它划分了512MB的空间,然后启动之, ... -
Android Service 之三(Bind Service, 继承自 Binder 类)
2011-08-10 13:08 29956之前提及过,启动Service有两种方式:startServ ... -
android service 之二(IntentService)
2011-08-09 11:13 31660不管是何种Service,它默认都是在应用程序的主线程(亦即U ... -
android service 之一 (start service)
2011-08-08 15:45 13909我们有两种方式(start与bind)启动一个Service ... -
写Service Demo的时候遇到的一个问题小结一下
2011-08-08 14:29 8513我写了一个 Service 的Demo,但是将启动Servi ... -
百度Android工程师面试题
2011-07-28 09:49 2216百度Android工程师面试题 -
Android中UI主线程与子线程
2011-07-26 14:10 2093在一个Android 程序开始运行的时候,会单独启动一个Pro ... -
Android线程模型(Painless Threading)
2011-07-26 14:07 1556当第一次启动一个Android ... -
Android 之 传感器 应用
2011-07-26 10:42 5262传感器的使用 1.传感器类型: 方向、加速度(重力)、 ... -
Logcat出错:Could not create the view: For input string:
2011-07-22 13:39 2527使用eclipse开发android应用已经一年多了,但今 ... -
Goolge Map API 源码
2011-07-14 14:16 3845由于做GOOGLE MAP 的项目,所以就上网想找它的源码。结 ... -
如何用metersToEquatorPixels实现任意纬度的米到像素的转换
2011-07-14 13:40 4727今天又是神奇的发现:我希望在MapView的Overlay子类 ... -
申请 android google map API key(转)
2011-07-10 14:07 18391.首先要得到你的debug keystore位置: ... -
windows下如何批量下载android源码
2011-05-18 22:56 2593为了在windows下批量下载Android的源码,上网查 ...
相关推荐
AIDL(Android Interface Definition Language)是Android系统提供的一种接口定义语言,用于在不同进程间进行通信,特别是当服务(Service)需要与客户端(如Activity)跨进程交互时。AIDL帮助开发者定义接口,使得...
在Android应用开发中,`Service`和`AIDL(Android Interface Definition Language)`是两个非常重要的组件,它们分别用于后台长时间运行的任务和服务间通信。本文将深入探讨这两个概念以及如何通过`AIDL`来实现服务...
有时,我们可能需要在Service和另一个应用组件之间进行更复杂的通信,例如双向交互,这时可以利用Android Interface Definition Language(AIDL)来实现。本文将深入探讨如何使用AIDL在Service与Client之间实现绑定...
**Android AIDL(Android Interface Definition Language)详解** 在Android系统中,进程间的通信(IPC, Inter-Process Communication)是...掌握AIDL的使用,对于开发大型的、需要多进程协作的Android应用至关重要。
总的来说,AIDL是Android平台中进行进程间通信的关键技术,理解并熟练使用AIDL,能够帮助开发者构建更加健壮和高效的Android应用。通过不断的实践和学习,开发者可以更好地掌握AIDL的精髓,提高应用的可扩展性和复用...
在Android应用开发中,Service和AIDL(Android Interface Definition Language)是两个重要的组件。Service用于在后台执行长时间运行的任务,而AIDL则用于进程间通信(IPC, Inter-Process Communication)。下面将...
在这个"Android AIDL使用例子"中,`MyBinderService`很可能包含了上述所有步骤的实现,展示了如何创建、实现AIDL接口以及在客户端和服务端之间进行通信。通过这个例子,开发者可以更深入地理解Android进程间通信的...
现在,我们来详细探讨如何通过AIDL在Android中实现RemoteService。 首先,让我们理解AIDL的基本概念。AIDL本质上是一个接口定义语言,它允许你在Android应用中定义一套接口,这些接口可以被其他应用所调用。当你...
本篇文章将深入探讨如何在Android中使用AIDL来实现进程间通信。 首先,理解AIDL的基本概念。AIDL是一种接口定义语言,类似于Java中的接口,但它的目的是跨越进程边界。通过AIDL,我们可以定义一个接口,该接口会被...
本示例“android aidl service”是一个演示如何使用AIDL进行数据交换的实践项目,它包括两个部分:AIDLServer(服务端)和AIDLClient(客户端)。通过这两个组件,我们可以深入理解AIDL的工作原理及其在实际应用中的...
本篇将深入探讨Activity和Service的生命周期以及如何利用Android Interface Definition Language (AIDL)进行进程间通信。 Activity是Android应用程序的用户界面,它负责与用户交互。Activity的生命周期分为几个关键...
本篇文章将深入探讨如何使用AIDL(Android Interface Definition Language)、Parcelable接口以及如何实现远程服务,这些都是Android Service开发中的关键知识点。 首先,我们来谈谈AIDL。AIDL是Android系统提供的...
总结起来,使用AIDL在Service中传递复杂类型如图片,需要对Android IPC机制有深入理解,包括AIDL接口定义、数据类型转换以及Service的生命周期管理。这是一个涉及到多方面技术的综合问题,需要开发者具备扎实的...
2. 在服务(Service)的onBind方法中返回IMyService的Binder实例。 客户端使用: 1. 客户端通过bindService方法连接到服务,获取到IBinder对象。 2. 将IBinder转换为IMyService的接口实例,然后就可以调用远程服务...
- 压缩包中的`ServiceAIDL`可能包含了一个完整的示例项目,包括服务端的`IService.aidl`、`MyService.java`,以及客户端的连接和调用代码。通过分析和运行这个项目,你可以更深入地理解AIDL的工作原理和应用场景。 ...
在Android开发中,服务(Service)是四大组件之一,它在后台执行长时间运行的操作而不会与用户界面交互。本文将深入探讨"Android startService, bindService, Aidl service基础全"这一主题,按照学习顺序依次讲解`...
本教程将深入讲解如何使用AIDL在Android开发中构建一个简单的跨进程通信DEMO。 首先,我们需要理解AIDL的基本概念。AIDL是一种基于文本的接口定义语言,类似于Java或C++的接口定义。通过AIDL,我们可以定义服务端...
本教程将详细讲解如何实现Android Service以及使用AIDL来创建远程服务。 首先,让我们深入了解Android的Service。Service是一种在后台运行的组件,即使用户没有直接与应用交互,它也能执行任务。Service可以用于...
在Android系统中,AIDL(Android Interface Definition Language)是一种接口定义语言,用于实现不同进程间的通信,即远程进程通讯。AIDL使得服务(Service)和活动(Activity)这两个独立的APK之间能够相互通信,...
1. 使用AIDL进行对象传递时,必须确保服务端和客户端使用的`aidl`文件以及对应的Java类是一致的。 2. 对象必须实现`Parcelable`接口,因为这是Android系统支持跨进程传递的唯一方式。 3. 进程间通信可能会出现性能...