Android进程间通信之使用AIDL

AIDL(Android Interface Definition Language ),可实现进程间的通信,并且允许多线程访问。(如果需要进程间通信,又不需要处理多线程访问,那么使用Messenger的方式更为合适),实现AIDL,需要以下几个步奏。

1.定义AIDL接口

AIDL接口使用后缀名为.aidl的文件来定义(例如创建一个IRemoteData.aidl),使用java语法来编写,在编译时,Android sdk工具会在/gen目录下生成一个java文件(IRemoteData.java),此文件内有一个静态内部抽象类Stub,继承了Binder类并实现了接口(IRemoteData)。它提供了一个asInterface(android.os.IBinder obj)把IBinder对象转换成我们声明的接口类型(实际上就是在Service端对Stub的实现)。

AIDL支持以下五种数据类型:java基本数据类型(int,char,boolean等),String,CharSequence,List和Map。如果你要在AIDL中使用其他数据类型,那么必须使用import导入,即使该类型和aidl处于同一包中。其次,所有非原始数据类型都必须指定参数方向,传入参数用关键字in表示,传出参数用out,传入传出参数用inout,基本数据类型都是传入值。

 1 package com.young.testserver.aidl;
 2
 3 import com.young.testserver.aidl.Person;
 4
 5 interface IRemoteData {
 6     int getRemoteData();
 7     void setRemoteData(int data);
 8
 9     Person getPerson();
10     void setPerson(in Person person);
11 }

由于该aidl文件中使用了非原始数据类型Person,所以需要创建一个aidl文件对Person进行声明

1 package com.young.testserver.aidl;
2
3 parcelable Person;

2.创建服务端Service,将我们对AIDL接口的实现通过onBind()方法返出去。

 1 public class AidlRemoteService extends Service {
 2
 3     // IRemoteData.Stub的具体实现
 4     private class RemoteData extends IRemoteData.Stub {
 5         int data;
 6         Person person;
 7         @Override
 8         public int getRemoteData() throws RemoteException {
 9             return data;
10         }
11
12         @Override
13         public void setRemoteData(int data) throws RemoteException {
14             this.data = data;
15         }
16
17         @Override
18         public Person getPerson() throws RemoteException {
19             return person;
20         }
21
22         @Override
23         public void setPerson(Person person) throws RemoteException {
24             this.person = person;
25         }
26
27     }
28
29     @Override
30     public IBinder onBind(Intent intent) {
31         // 将实现的IRemoteData.Stub类返出去,客户端可以使用Stub提供的asInterface获得
32         return new RemoteData();
33     }
34 }

3.将服务端对应的aidl文件与java文件拷贝到客户端,在客户端绑定服务时,使用Stub类提供的asInterface获取服务端实现的接口类,然后使用这个已实现的接口类就可以调用AIDL中的函数。

 1 public class AidlClientActivity extends Activity {
 2
 3     private static final String TAG = "--DEBUG--";
 4   
 5     private static final String BIND_ACTION = "com.young.server.START_AIDL_SERVICE";
 6     private Button mBindBtn;
 7
 8     @Override
 9     protected void onCreate(Bundle savedInstanceState) {
10         super.onCreate(savedInstanceState);
11         setContentView(R.layout.activity_aidl_client);
12
13         mBindBtn = (Button) findViewById(R.id.bind_service);
14         mBindBtn.setOnClickListener(new OnClickListener() {
15             @Override
16             public void onClick(View v) {
17                 bindService(new Intent(BIND_ACTION), conn, Context.BIND_AUTO_CREATE);
18             }
19         });
20     }
21
22     private ServiceConnection conn = new ServiceConnection() {
23
24         @Override
25         public void onServiceDisconnected(ComponentName name) {
26             Log.v(TAG, "AIDL 服务已断开");
27         }
28
29         @Override
30         public void onServiceConnected(ComponentName name, IBinder service) {
31             Log.v(TAG, "AIDL 服务已链接");
32
33             // 获得服务端对Stub的实现
34             IRemoteData remoteData = IRemoteData.Stub.asInterface(service);
35             try {
36                 remoteData.setRemoteData(123456);
37                 int data = remoteData.getRemoteData();
38                 Log.v(TAG, "client get remote data=" + data);
39
40                 remoteData.setPerson(new Person("Allen", 25));
41                 Person person = remoteData.getPerson();
42                 Log.v(TAG, "client get remote Person=" + person.toString());
43             } catch (RemoteException e) {
44                 e.printStackTrace();
45             }
46         }
47     };
48 }

4.通过AIDL在进程间传递对象,需要符合以下几点要求

(1)实现Parcelable接口。

(2)实现writeToParcel方法,以便将当前对象状态写入Parcel中。

(3)增加一个名为CREATOR的静态变量,实现Parcelable.Creator<T>接口

(4)创建一个AIDL文件来声明这个类(见上文的Person.aidl)

 1 public class Person implements Parcelable {
 2
 3     private String name;
 4     private int age;
 5
 6     public Person(String name, int age) {
 7         super();
 8         this.name = name;
 9         this.age = age;
10     }
11
12     public String getName() {
13         return name;
14     }
15
16     public void setName(String name) {
17         this.name = name;
18     }
19
20     public int getAge() {
21         return age;
22     }
23
24     public void setAge(int age) {
25         this.age = age;
26     }
27
28     @Override
29     public String toString() {
30         return "Person [name=" + name + ", age=" + age + "]";
31     }
32
33     // -------------分割线---------------
34
35     // 注意读入和写出顺序
36     public Person(Parcel parcel) {
37         name = parcel.readString();
38         age = parcel.readInt();
39     }
40
41     public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>() {
42
43         @Override
44         public Person createFromParcel(Parcel source) {
45             return new Person(source);
46         }
47
48         @Override
49         public Person[] newArray(int size) {
50             return new Person[size];
51         }
52
53     };
54
55     @Override
56     public int describeContents() {
57         return 0;
58     }
59
60     @Override
61     public void writeToParcel(Parcel dest, int flags) {
62         dest.writeString(name);
63         dest.writeInt(age);
64     }

最后运行程序,打印日志结果如下,客户端取到了从客户端传给服务端的数据。

11-13 15:56:23.081: V/--DEBUG--(25361): AIDL 服务已链接
11-13 15:56:23.081: V/--DEBUG--(25361): client get remote data=123456
11-13 15:56:23.081: V/--DEBUG--(25361): client get remote Person=Person [name=Allen, age=25]

时间: 2024-12-24 07:32:57

Android进程间通信之使用AIDL的相关文章

android进程间通信:使用AIDL

欢迎阅读本文,你能关注本文,你知道你需要进程间通信.需要AIDL(以及Binder),那么可以默认你对这些概念已经有了一些了解,你(大致)知道它们是什么,它们有什么用,所以为了节约大家的眼力和时间,在此我不复制粘贴网上泛滥的博客或者翻译冗长的android文档. 关于AIDL的介绍在文档:docs/guide/developing/tools/aidl.html 关于IBinder的介绍在文档:docs/reference/android/os/IBinder.html 以及Binder:doc

Android Studio中使用AIDL进行进程间通信

什么是AIDL aidl是 Android Interface definition language的缩写,也就是安卓接口定义语言 为什么要有AIDL AIDL允许你定义客户端与服务端达成一致的程序接口使用进程间通信相互交流. 在Android上面,一个进程不能正常的访问另一个进程的内存. 所以说,他们需要分解他们的对象为操作系统可以理解的基本单位,然后为你把这些对象按次序跨越进程边界 ,书写这些代码是单调冗长的,所以android使用AIDL为你处理这个问题. 注意:使用AIDL只有在你允许

Android进程间通信之----Aidl传递对象

转载请注明出处 CSDN废墟的树 前言 有关Android进程间通信之Aidl编程的基本使用步骤已经在上一篇博客中有讲解,Android studio 下的aidl编程实现Android的夸进程间通信.上一篇博客中只是演示了怎么利用Aidl实现跨进程间传递Java基本类型,以及Aidl传递Bitamap对象.可能在一些场景下你需要跨进程传递一个对象,那么Aidl是否能传递一个对象呢?答案是肯定的,网上也有很多相关的资料,之所以写这篇博客:一是当作自己学习笔记咯,二是把自己遇到的问题分享出来. A

AIDL实现Android进程间通信实例

实现Android进程间通信实例有好几种方法: 1,AIDL 2,Broadcast 3,Intent 4,Content Provider 记录一下AIDL实现Android进程间通信的方式: Android的AIDL进程间通信实现步骤: 一:创建AIDL服务端:aidl文件,自动生成的接口java文件,服务service xxxInterface.aidl  (远程服务的接口定义) package com.example.aidltest; interface IMyAidlInterfac

Android studio 下的aidl编程实现Android的夸进程间通信

前言 Android中夸进程间通信方式有很多种方式,比如:aidl,Messenger,文件共享,广播(BroadCast),ContentProvider,Socket(网络通信).每种方式都有自己的使用场景和优缺点,接下来几篇博客我们一一学习他们是怎么使用的.这篇博客主要是介绍Android studio下实现aidl编程. AIDL的使用步骤 aidl远程调用传递的参数和返回值支持Java的基本类型(int long booen char byte等)和String,List,Map等.当

Android进程间通信(IPC)的AIDL机制:Hello World示例

Android实现IPC可使用Android本身提供的AIDL机制.网上也有很多相关文章,但写的过于繁琐和麻烦,重点也不突出.本文抽丝剥茧从工程角度给出一个最简单的Android AIDL例程关键代码,以最简单的形式说明如何在代码中使用Android AIDL. AIDL首先在逻辑上可分为"服务端"和"客户端".在本示例中,则以两个完全不同.互相独立的Eclipse 项目代表. (1)server.一个Android App,即AIDL的服务端服务提供者. (2)c

【翻译】Android Interface Definition Language (AIDL)

参考地址:https://developer.android.com/guide/components/aidl.html Android Interface Definition Language (AIDL) AIDL (Android Interface Definition Language) is similar to other IDLs you might have worked with. It allows you to define the programming inter

Android进程间通信

如果想要进行IPC通信,一般写一个AIDL接口,再写一个Service子类,然后实现AIDL接口 当做IBinder返回给Activity界面层. 如果不想写AIDL接口文件,只是单线程中与Service进行通信 我们可以用Android写好的Messenger类来处理,一样能将消息传递给Service进行通信. 什么是aidl: aidl是 Android Interface definition language的缩写,它是一种android内部进程通信接口的描述语言,通过它我们可以定义进程

Android IPC机制(三)在Android Studio中使用AIDL实现跨进程方法调用

在上一篇文章Android IPC机制(二)用Messenger进行进程间通信中我们介绍了使用Messenger来进行进程间通信的方法,但是我们能发现Messenger是以串行的方式来处理客户端发来的信息,如果有大量的消息发到服务端,服务端仍然一个一个的处理再响应客户端显然是不合适的.另外,Messenger用来进程间进行数据传递但是却不能满足跨进程的方法调用,接下来我们来使用AIDL来实现跨进程方法调用,此前我们都是用Eclipse来实现的,这次我们看看在Android Studio中使用AI