1、创建.aidl 文件

AIDL 语法简单,用来声明接口,其中的方法接收参数和返回值,但是参数和返回值的类型是有约束的,且有些类型是需要 import,另外一些则无需这样做。

AIDL 支持的数据类型划分为四类,第一类是 Java 编程语言中的基本类型,第二类包括 String、List、Map 和 CharSequence,第三类是其他 AIDL 生成的 interface,第四类是实现了 Parcelable protocol 的自定义类。

其中,除了第一类外,其他三类在使用时均需要特别小心。

使用第二类时,首先需要明白这些类不需要 import,是内嵌的。其次注意在使用 List 和 Map 此二者容器类时,需注意其元素必须得是 AIDL 支持的数据类型,List 可支持泛型,但是 Map 不支持,同时另外一端负责接收的具体的类里则必须是 ArrayListHashMap

使用第三、四类时,需要留意它们都是需要 import 的,但是前者传递时,传递的是 reference,而后者则是 value。

在创建 .aidl 文件的过程中,应该注意一旦 method 有参数,则需注意在前面加上 in, out 或 inout,它们被称为 directional tag,但是对于基本类型的参数,默认就是 in,并且不会是其他值。

Aidl默认支持的类型包话java基本类型(int、long、boolean等)和(String、List、Map、CharSequence),如果要传递自定义的类型该如何实现呢? 
要传递自定义类型,首先要让自定义类型支持parcelable协议,实现步骤如下: 
1>自定义类型必须实现Parcelable接口,并且实现Parcelable接口的public void writeToParcel(Parcel dest, int flags)方法 。 
2>自定义类型中必须含有一个名称为CREATOR的静态成员,该成员对象要求实现Parcelable.Creator接口及其方法。 
3> 创建一个aidl文件声明你的自定义类型。 
Parcelable接口的作用:实现了Parcelable接口的实例可以将自身的状态信息(状态信息通常指的是各成员变量的值)写入Parcel,也可以从Parcel中恢复其状态。 Parcel用来完成数据的序列化传递。

1> 创建自定义类型,并实现Parcelable接口,使其支持parcelable协议。如:在cn.jp.domain包下创建Person.java:

package cn.jp.domain;
import android.os.Parcel;
import android.os.Parcelable;
public class Person implements Parcelable
private Integer id;
private String name;
public Person(){}
public Person(Integer id, String name) {
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {//把javanbean中的数据写到Parcel
dest.writeInt(this.id);
dest.writeString(this.name);
}
//添加一个静态成员,名为CREATOR,该对象实现了Parcelable.Creator接口
public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>(){
@Override
public Person createFromParcel(Parcel source) {//从Parcel中读取数据,返回person对象
return new Person(source.readInt(), source.readString());
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
}

2> 在自定义类型所在包下创建一个aidl文件对自定义类型进行声明,文件的名称与自定义类型同名。

package cn.jp.domain;
parcelable Person;

3> 在接口aidl文件中使用自定义类型,需要使用import显式导入,本例在cn.jp.aidl包下创建IPersonService.aidl文件,内容如下:

package cn.itcast.aidl; 
import cn.itcast.domain.Person;
interface IPersonService {
      void save(in Person person);
}

4> 在实现aidl文件生成的接口(本例是IPersonService),但并非直接实现接口,而是通过继承接口的Stub来实现(Stub抽象类内部实现了aidl接口),并且实现接口方法的代码。内容如下:

public class ServiceBinder extends IPersonService.Stub {
@Override
public void save(Person person) throws RemoteException {
Log.i("PersonService", person.getId()+"="+ person.getName());
}
}

5> 创建一个Service(服务),在服务的onBind(Intent intent)方法中返回实现了aidl接口的对象(本例是ServiceBinder)。内容如下:

public class PersonService extends Service {
private ServiceBinder serviceBinder = new ServiceBinder();
@Override
public IBinder onBind(Intent intent) {
return serviceBinder;
}
public class ServiceBinder extends IPersonService.Stub {
@Override
public void save(Person person) throws RemoteException {
Log.i("PersonService", person.getId()+"="+ person.getName());
}
}
}

其他应用可以通过隐式意图访问服务,意图的动作可以自定义,AndroidManifest.xml配置代码如下:

<service android:name=".PersonService" >
<intent-filter>
<action android:name="cn.jp.process.aidl.PersonService " />
</intent-filter>
</service>

6> 把应用中的aidl文件和所在package一起拷贝到客户端应用的src目录下,eclipse会自动在客户端应用的gen目录中为aidl文件同步生 成IPersonService.java接口文件,接下来再把自定义类型文件和类型声明aidl文件及所在package一起拷贝到客户端应用的src 目录下。 
最后就可以在客户端应用中实现与远程服务的通信,代码如下:

public class ClientActivity extends Activity { 
private IPersonService personService;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
this.bindService(new Intent("cn.jp.process.aidl.PersonService"), this.serviceConnection, BIND_AUTO_CREATE);//绑定到服务
}
@Override
protected void onDestroy() {
super.onDestroy();
this.unbindService(serviceConnection);//解除服务
}
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
personService = IPersonService.Stub.asInterface(service);
try {
personService.save(new Person(56,"liming"));
} catch (RemoteException e) {
Log.e("ClientActivity", e.toString());
}

[Android Pro] AIDL进程间传递自定义类型参数的更多相关文章

  1. Android学习笔记_23_服务Service之AIDL和远程服务实现进程通信以及进程间传递自定义类型参数

    一.了解AIDL语言: 在Android中, 每个应用程序都有自己的进程,当需要在不同的进程之间传递对象时,该如何实现呢? 显然, Java中是不支持跨进程内存共享的.因此要传递对象, 需要把对象解析 ...

  2. android 进程间通信 messenger 是什么 binder 跟 aidl 区别 intent 进程间 通讯? android 消息机制 进程间 android 进程间 可以用 handler么 messenger 与 handler 机制 messenger 机制 是不是 就是 handler 机制 或 , 是不是就是 消息机制 android messenge

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha messenger 是什么 binder 跟 aidl 区别 intent 进程间 通讯 ...

  3. AIDL进程间调用与Binder的简单介绍

    Binder是安卓中特有的一种进程间通信(IPC)方式,从Unix发展而来的手段,通信双方必须处理线程同步.内存管理等复杂问题,传统的Socket.匿名通道(Pipe).匿名管道(FIFO).信号量( ...

  4. IBinder对象在进程间传递的形式(一)

    命题 当service经常被远程调用时,我们经常常使用到aidl来定一个接口供service和client来使用,这个事实上就是使用Binder机制的IPC通信.当client bind servic ...

  5. Android消息传递之组件间传递消息

    前言: 上篇学习总结了Android通过Handler消息机制实现了工作线程与UI线程之间的通信,今天来学习一下如何实现组件之间的通信.本文依然是为学习EventBus做铺垫,有对比才能进步,今天主要 ...

  6. C#中使用SendMessage在进程间传递数据的实例

    原文:C#中使用SendMessage在进程间传递数据的实例 1 新建解决方案SendMessageExample 在解决方案下面新建三个项目:CopyDataStruct,Receiver和Send ...

  7. 进程间传递文件描述符——sendmsg和recvmsg函数

    先引入一个例子,该程序的目的是子进程向父进程传递文件描述符,并通过该文件描述符读取buf. #include <func.h> int main(){ int fds[2]; pipe(f ...

  8. WPF 进程间传递参数

    WPF 进程间传递参数          在软件开发中有时需要在一个软件中启动另一个软件,这时用Process.Start(“软件路径”)可以启动另一个软件.如果在这个过程中还需要传递一些参数给新启动 ...

  9. 进程间传递文件描述符fd

    众所周知,子进程会继承父进程已经打开的文件描述符fd,但是fork之后的是不会被继承的,这个时候是否无能无力了?答应是NO.Linux提供了一个系统调用sendmsg,借助它,可以实现进程间传递文件描 ...

随机推荐

  1. jquery选择器(二)-层次选择器

    1. 后代选择器 2. 子元素选择器 3. 相邻兄弟元素选择器 4. 一般兄弟元素选择器(同辈元素选择器) 5. 补充(除自身以外的前后同辈选择器)

  2. umeng

    http://bbs.umeng.com/thread-5408-1-1.html 微博分享 http://dev.umeng.com/social/ios/operation#2_2 http:// ...

  3. HDU 5014 Number Sequence(位运算)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5014 解题报告:西安网赛的题,当时想到一半,只想到从大的开始匹配,做异或运算得到对应的b[i],但是少 ...

  4. Ngui 五种点击事件实现方式及在3d场景中点透的情况

    http://www.unity蛮牛.com/thread-22018-1-1.html ngui作为unity界面插件之一中,无疑是最好用,使用最多的了从自学unity到现在界面一直使用它 由于它的 ...

  5. Unity手游之路<三> 基于Unity+Java的聊天室源码

    http://blog.csdn.net/janeky/article/details/17233199 项目介绍 这是一个简单的Unity项目,实现最基本的聊天室群聊功能.登录聊天室后,用户可以输入 ...

  6. C++变量对比java变量所占内存

    C++ char 1 short int 2 int 4 long int 8 float 4 double 8 long double 8 下面是计算程序: #include<math.h&g ...

  7. 补上题代码 hdu1520

    #include<iostream> #include<cmath> #include<algorithm> #include<vector> #inc ...

  8. linux中用shell获取昨天、明天或多天前的日期

    linux中用shell获取昨天.明天或多天前的日期 时间 -- :: BlogJava-专家区 原文 http://www.blogjava.net/xzclog/archive/2015/12/0 ...

  9. PHP的反射类ReflectionClass、ReflectionMethod使用实例

    PHP5 具有完整的反射API,添加对类.接口.函数.方法和扩展进行反向工程的能力. 反射是什么? 它是指在PHP运行状态中,扩展分析PHP程序,导出或提取出关于类.方法.属性.参数等的详细信息,包括 ...

  10. ADO.NET和ADO.NET Entity Framework

    ADO.NET 3.0 用于访问和操作数据的两个主要组件是 .NET Framework 数据提供程序和 DataSet. .NET Framework 数据提供程序 .NET Framework 数 ...