在Android中, 每个应用程序都可以有自己的进程。在写UI应用的时候,经常要用到Service。在不同的进程中, 怎样传递对象呢?显然,Java中不允许跨进程内存共享。因此传递对象,只能把对象拆分成操作系统能理解的简单形式,以达到跨界对象访问的目的。在J2EE中,采用RMI的方式,可以通过序列化传递对象。在Android中,则采用AIDL的方式。
这篇博文就来个具体的实现:AIDL进程间通信实现独立下载功能。
什么是AIDL,如何实现?
什么是AIDL呢?
AIDL(AndRoid接口描述语言)是一种接口描述语言;编译器可以通过aidl文件生成一段代码,通过预先定义的接口达到两个进程内部通信进程的目的。如果需要在一个Activity中,访问另一个Service中的某个对象,需要先将对象转化成AIDL可识别的参数(可能是多个参数),然后使用AIDL来传递这些参数,在消息的接收端,使用这些参数组装成自己需要的对象。
AIDL的IPC的机制和COM或CORBA类似, 是基于接口的,但它是轻量级的。它使用代理类在客户端和实现层间传递值。如果要使用AIDL,需要完成2件事情:
- 引入AIDL的相关类;
- 调用aidl产生的class。
该实现分成了两个项目,一个是服务端,一个是客户端。服务端就是Service,运行在后台;客户端就是和Service通信的另一方了。
Android DownLoadService服务端实现
android 下载队列类 Queue.java
该类用于生成一个下载队列,也是服务端与客户端通信的数据单元
package com.obatu.services.aidl;
import android.os.Parcel;
import android.os.Parcelable;
public class Queue implements Parcelable {
private int id; //队列id
private String name; //显示在进度条上的文字
private String url; //下载的URL地址,必须是一个标准url地址
private String savePath; //保存到sdcard的路径,必须是一个完整路径
private String downingIntent; //下载过程会在status bar生成一个notify,
//点击notify会跳转到该intent指向的Activity。其实质是一个action字符串,如:com.obatu.client.QueueList
private String completeIntent; //下载完成后点击notify跳转到的Activity,同上解释
private long fileLength = 0; //文件总长度,该字段会在开始下载的时候写入
private long downSize = 0; //已经下载的字节数
private boolean cancel = false; //是否已经取消该队列,用于控制取消下载
private boolean autoRun = false;//下载完成后,是否自动执行completeIntent
//必须提供一个名为CREATOR的static final属性 该属性需要实现android.os.Parcelable.Creator<T>接口
public static final Parcelable.Creator<Queue> CREATOR = new Parcelable.Creator<Queue>() {
@Override
public Queue createFromParcel(Parcel source) {
return new Queue(source);
}
@Override
public Queue[] newArray(int size) {
return new Queue[size];
}
};
public Queue() {
}
private Queue(Parcel source){
readFromParcel(source);
}
public void readFromParcel(Parcel source) {
id = source.readInt();
name = source.readString();
url = source.readString();
savePath = source.readString();
downingIntent = source.readString();
completeIntent = source.readString();
fileLength = source.readLong();
downSize = source.readLong();
boolean[] b = new boolean[2];
source.readBooleanArray(b);
if(b.length > 0){
cancel = b[0];
autoRun = b[1];
}
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flag) {
dest.writeInt(id);
dest.writeString(name);
dest.writeString(url);
dest.writeString(savePath);
dest.writeString(downingIntent);
dest.writeString(completeIntent);
dest.writeLong(fileLength);
dest.writeLong(downSize);
boolean[] b = {cancel,autoRun};
dest.writeBooleanArray(b);
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getSavePath() {
return savePath;
}
public void setSavePath(String savePath) {
this.savePath = savePath;
}
public String getDowningIntent() {
return downingIntent;
}
public void setDowningIntent(String downingIntent) {
this.downingIntent = downingIntent;
}
public String getCompleteI