跨进程调用Service(AIDL Service)

1.什么是aidl:aidl是 Android Interface definition language的缩写,一看就明白,它是一种android内部进程通信接口的描述语言,通过它我们可以定义进程间的通信接口

icp:interprocess communication :内部进程通信

2.既然aidl可以定义并实现进程通信,那么我们怎么使用它呢?文档/android-sdk/docs/guide/developing/tools/aidl.html中对步骤作了详细描述:

--1.Create your .aidl file - This file defines an interface (YourInterface.aidl) that defines the methods and fields available to a client.

创建你的aidl文件,我在后面给出了一个例子,它的aidl文件定义如下:写法跟java代码类似,但是这里有一点值得注意的就是它可以引用其它aidl文件中定义的接口,但是不能够引用你的java类文件中定义的接口

[java] view
plain
copy

  1. package com.cao.android.demos.binder.aidl;
  2. import com.cao.android.demos.binder.aidl.AIDLActivity;
  3. interface AIDLService {
  4. void registerTestCall(AIDLActivity cb);
  5. void invokCallBack();
  6. }

--2.Add the .aidl file to your makefile - (the ADT Plugin for Eclipse manages this for you). Android includes the compiler, called AIDL, in the tools/ directory.

编译你的aidl文件,这个只要是在eclipse中开发,你的adt插件会像资源文件一样把aidl文件编译成java代码生成在gen文件夹下,不用手动去编译:编译生成AIDLService.java如我例子中代码

--3.Implement your interface methods - The AIDL compiler creates an interface in the Java programming language from your AIDL interface. This interface has an inner abstract class named Stub that inherits the interface (and implements a few additional methods
necessary for the IPC call). You must create a class that extends YourInterface.Stub and implements the methods you declared in your .aidl file.

实现你定义aidl接口中的内部抽象类Stub,public static abstract class Stub extends android.os.Binder implements com.cao.android.demos.binder.aidl.AIDLService

Stub类继承了Binder,并继承我们在aidl文件中定义的接口,我们需要实现接口方法,下面是我在例子中实现的Stub类:

[java] view
plain
copy

  1. private final AIDLService.Stub mBinder = new AIDLService.Stub() {
  2. @Override
  3. public void invokCallBack() throws RemoteException {
  4. Log("AIDLService.invokCallBack");
  5. Rect1 rect = new Rect1();
  6. rect.bottom=-1;
  7. rect.left=-1;
  8. rect.right=1;
  9. rect.top=1;
  10. callback.performAction(rect);
  11. }
  12. @Override
  13. public void registerTestCall(AIDLActivity cb) throws RemoteException {
  14. Log("AIDLService.registerTestCall");
  15. callback = cb;
  16. }
  17. };

Stub翻译成中文是存根的意思,注意Stub对象是在被调用端进程,也就是服务端进程,至此,服务端aidl服务端得编码完成了。

--4.Expose your interface to clients - If you‘re writing a service, you should extend Service and override Service.onBind(Intent) to return an instance of your class that implements your interface.

第四步告诉你怎么在客户端如何调用服务端得aidl描述的接口对象,doc只告诉我们需要实现Service.onBind(Intent)方法,该方法会返回一个IBinder对象到客户端,绑定服务时不是需要一个ServiceConnection对象么,在没有了解aidl用法前一直不知道它是什么作用,其实他就是用来在客户端绑定service时接收service返回的IBinder对象的:

[java] view
plain
copy

  1. AIDLService mService;
  2. private ServiceConnection mConnection = new ServiceConnection() {
  3. public void onServiceConnected(ComponentName className, IBinder service) {
  4. Log("connect service");
  5. mService = AIDLService.Stub.asInterface(service);
  6. try {
  7. mService.registerTestCall(mCallback);
  8. } catch (RemoteException e) {
  9. }
  10. }
  11. public void onServiceDisconnected(ComponentName className) {
  12. Log("disconnect service");
  13. mService = null;
  14. }
  15. };

mService就是AIDLService对象,具体可以看我后面提供的示例代码,需要注意在客户端需要存一个服务端实现了的aidl接口描述文件,但是客户端只是使用该aidl接口,不需要实现它的Stub类,获取服务端得aidl对象后mService = AIDLService.Stub.asInterface(service);,就可以在客户端使用它了,对mService对象方法的调用不是在客户端执行,而是在服务端执行。

4.aidl中使用java类,需要实现Parcelable接口,并且在定义类相同包下面对类进行声明:

上面我定义了Rect1类

之后你就可以在aidl接口中对该类进行使用了

package com.cao.android.demos.binder.aidl;

import com.cao.android.demos.binder.aidl.Rect1;

interface AIDLActivity {

void performAction(in Rect1 rect);

}

注意in/out的说明,我这里使用了in表示输入参数,out没有试过,为什么使用in/out暂时没有做深入研究。

作出说明

例子实现了一个AIDLTestActivity,AIDLTestActivity通过bindservice绑定一个服务AIDLTestService,通过并获取AIDLTestActivity的一个aidl对象AIDLService,该对象提供两个方法,一个是registerTestCall注册一个aidl对象,通过该方法,AIDLTestActivity把本身实现的一个aidl对象AIDLActivity传到AIDLTestService,在AIDLTestService通过操作AIDLActivity这个aidl远端对象代理,使AIDLTestActivity弹出一个toast,完整例子见我上传的资源:

http://download.csdn.net/source/3284820

文章仓促而成,有什么疑问欢迎大家一起讨论。

时间: 2024-08-02 12:09:48

跨进程调用Service(AIDL Service)的相关文章

Android中的跨进程调用技术AIDL

什么是AIDL Android系统中的进程之间不能共享内存,因此,需要提供一些机制在不同进程之间进行数据通信. 为了使其他的应用程序也可以访问本应用程序提供的服务,Android系统采用了远程过程调用(Remote Procedure Call,RPC)方式来实现. 与很多其他的基于RPC的解决方案一样,Android使用一种接口定义语言(Interface Definition Language,IDL)来公开服务的接口. Android的四大组件中的三个(Activity.Broadcast

Android学习笔记二十六.跨进程调用Service(AIDL Service)

跨进程调用Service(AIDL Service) 一.AIDL Service 1.什么是AIDL Service? AIDL,即Android Interface Definition Language.是Android用于定义远程接口,AIDL接口定义语言的语法比较简单,这种接口定义语言并不是真正的编程语言,它只是定义两个进程之间的通信接口.AIDL的语法与Java接口很相似,但存在如下几点差异: (1)AIDL定义接口的源代码必须以.aidl结尾; (2)AIDL接口中用到数据类型,除

Abdroid---44---使用AIDL Service 实现跨进程调用Service

 为了实现跨进程通信(interprocess communication 简称 IPC),Android提供了AIDL Service. AIDL 是一种IDL语言,用于生成可以在Android设备上两个进程之间进行通信的代码 如果在一个进程中药调用另一个进程中对象的操作,就可以使用AIDL生成可序列化的参数. AIDL是面向接口的 与绑定本地Service不同的是,本地Service的onBind方法会直接把IBinder对象本身传给客户端的ServiceConnection 的onSe

跳出Robotium单进程限制,实现跨进程调用的两种方式浅谈

用过Robotium做Android自动化测试的同学都知道,Robotium因为继承了instrumentation而无法进行跨进程的调用,比如模拟按键点击(据说4.3以后instrumentation有了getUIAutomator的入口,然后就木有然后了,本人没有亲试且不在本文讨论中). 本人亲试了两种实现方式,经实验均能实现简单的事件,比如:发送按键.点击.长按.拖动等,最终的调用方式都采用4.1以后的input命令实现,当然你得是root.具体命令如下: [email protected

Android跨进程访问(AIDL服务)

我将AndroidAIDL的学习知识总结一下和大家共享 在Android开发中,AIDL主要是用来跨进程访问. Android系统中的进程之间不能共享内存,因此,需要提供一些机制在不同进程之间进行数据通信,一般是和Service服务组件一起使用来实现. 1.创建调用AIDL服务 建立AIDL服务的步骤: 第一步:在Eclipse的Android工程的Java源文件目录中建立一个扩展名为aidl的文件,改文件的语法类似于Java代码,但稍有不同. 第二步:如果aidl文件的内容是正确的,ADT会在

Android 跨进程调用忽略权限

Framework层: @Override    public StackInfo getStackInfo(int stackId) {        final int callingUid = Binder.getCallingUid(); // 拿到调用者身份        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {            // TODO         } long ident = Bind

Android四大组件——Service后台服务、前台服务、IntentService、跨进程服务、无障碍服务、系统服务

Service后台服务.前台服务.IntentService.跨进程服务.无障碍服务.系统服务 本篇文章包括以下内容: 前言 Service的简介 后台服务 不可交互的后台服务 可交互的后台服务 混合性交互的后台服务 前台服务 IntentService AIDL跨进程服务 AccessibilityService无障碍服务 系统服务 部分源码下载 前言 作为四大组件之一的Service类,是面试和笔试的必备关卡,我把我所学到的东西总结了一遍,相信你看了之后你会对Service娓娓道来,在以后遇

Android的服务(Service)(三)Service客户端的绑定与跨进程

继续上篇的分析,接下来是第三个问题"Service与其客户端的绑定如何实现,即跨进程调用问题" (一).Service的生命周期 (二).Service的自动重启问题 (三).Service与其客户端的绑定如何实现,即跨进程调用问题. 服务于客户端的绑定通过binder来实现的,就是客户端去bind服务.来看看ContextImpl的bindServiceCommon方法 private boolean bindServiceCommon(Intent service, Service

怎样用AIDL Service 传递复杂数据

大家都知道在Android中通过AIDL可以跨进程调用Service中的数据,网上也有很多实例,但是大部分实例都是关于基本数据类型的远程调用,很少讲到复杂数据的调用,今天我用一个例子来演示一下怎样用AIDL Service 传递复杂数据. 我们分2步开始: 第一步:部署我们的服务端,也就是Service端: 1:在Service端我先自定义2个类型:Person和Pet.因为我们需要跨进程传递Person对象和Pet对象,所以Person类和Pet类都必须实现Parcelable接口,并要求在实