在网上查看了好多的相关资料,大多数是用AsyncTask来实现相关的功能。但是只是实现了单个任务显示进度的,这并不是我们想要的功能,但是我们可以参考其中的一些代码或者思想。
话不多说,看一下完成后的相关界面。
(1)这是我们要的主界面(listview实现)
(2)
(3)
(3)
(4)
看完图片后,我来说一下我是怎样完成该功能。
1. 创建一个实体类.
package com.icss.entity;
import java.io.Serializable;
public class DownloadInfo implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* 初始化状态
*/
public final static int INIT = 0;
/**
* 停止下载
*/
public final static int PAUSED = 1;
/**
* 下载中
*/
public final static int DOWNING = 2;
/**
* 任务唤醒
*/
public final static int RESUME = 3;
/**
* 下载完成
*/
public final static int COMPLETED = 4;
/**
* 取消任务
*/
public final static int CALCELED = 5;
/**
* 任务id
*/
private String id;
/**
* 任务大小
*/
private long size;
/**
* 已经完成的进度
*/
private long complete;
/**
* 文件下载地址
*/
private String url;
/**
* 文件保存的路径
*/
private String path;
/**
* 任务当前的状态
*/
private int status;
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public long getSize() {
return size;
}
public void setSize(long size) {
this.size = size;
}
public long getComplete() {
return complete;
}
public void setComplete(long complete) {
this.complete = complete;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
}
2.创建一个Observable。可能你会奇怪,为什么要创建这样一个东西。其实你也可以用广播来实现,但是本人喜欢用观察者模式多点。这个类的作用是用来提醒观察队列中的成员来接收观察者发送过来的数据。相信大家应该都知道我的想法了,没错,我就是加adapter加入队列中,接收下载时的DownloadInfo数据,并刷新adapter.
3.线程。使用了AsyncTask类。并在后台执行时,启动线程去下载任务。 当然 你要把DownloadInfo作为参数放在AsyncTask类中,下载的同时,判断任务的状态,如果是下载状态就修改DownloadInfo中的下载进度数据,并通过Observable将更新的DownloadInfo发送到各个观察队列中去,提醒它们接收数据,并刷新ui。
4.adapter 类 implements Observer 并加入观察队列。
private Map infomap = new HashMap(); 将从下载器发送过来的DownloadInfo放进去,String 为任务的id。
(1)getview()函数中的一些方法
//任务不在infomap中,将其加进去,并设置相关的ui。
if (!infomap.containsKey(info.getId())) {
infomap.put(info.getId(), info);
//根据任务来设置item的ui。
setitembackground(info, holder);
}
if (infomap.containsKey(info.getId())) {
final DownloadInfo tinfo = infomap.get(info.getId());
setitembackground(tinfo, holder);
//设置相关的按钮事件
}
//设置相关的ui
private void setitembackground(DownloadInfo info, MyActiveViewHolder holder) {
String text = "开始";
int progress = 0;
switch (info.getStatus()) {
case DownloadInfo.DOWNING:
text = "下载中";
break;
case DownloadInfo.PAUSED:
text = "暂停";
break;
case DownloadInfo.COMPLETED:
text = "完成";
break;
default:
break;
}
progress = (int) info.getComplete();
holder.getStartButton().setText(text);
holder.getTextView().setText(progress + "%");
}
(2)
public void update(Observable observable, Object data) {
if (data instanceof DownloadInfo) {
DownloadInfo task = (DownloadInfo) data;
if(task.getStatus()!=DownloadInfo.CALCELED)
{
infomap.put(task.getId(), task);
}
this.notifyDataSetChanged();
}
}
就写到这里了,工程,我有个时间上传给大家。我的资源里有一个apk的例子,大家可以下载来看看。