众所周知,一个Android应用要想运行流畅,对于它所消耗的资源我们当然要进行一些管理,今天,我就用一个线程池的例子来管理线程所消耗的资源。
当然咯,肯定是利用线程池,我不会把Android所有的线程池全部都写在这,我觉得没有这个必要。为啥呢?你说为啥,哈哈,因为我自己也没那么牛;其次呢,我们也没这个必要吧。不废话了,来吧那就。
功能:动态添加线程,过滤重复任务,超时处理。
在这个线程池管理类中,我写了两个线程池,一个work线程池,一个timeout线程池。为啥要有超时线程池啊,你有木有发现,有时候我们发送一个http请求的时候,尼玛服务器半天都不给回复,还有就是我们在下载任务时,网络断开,此时我们的读写肯定是卡住的,所以我在此做了一个超时处理。直接来看怎么使用:
// DownloadPoolManager(1, 100) 1 表示同时执行线程的数量,如果是负数,那么默认为5 。100(单位s)表示所有的任务添加完成之后线程的轮询时间超过这个时间则停止线程池。
DownloadPoolManager downloadPoolManager = new DownloadPoolManager(1, 100);
//RequestTaskRunnble 这是一个请求接口类,你可以自己写一个实现类继承它,在你自己的线程里写你想干的事
//第一个参数表示你要请求的http地址,第二个参数表示请求的结果
RequestTaskRunnble requestTask = new RequestTaskRunnble("www.baidu.com",new RequestTaskStatusListener() {
@Override
public void statusListener(Object object) {
// do something
}
});
// RequestTimeoutTaskRunnble 这是一个请求失败的接口类,你可以自己写一个实现类继承它,在这里边检测 requestTask 的状态
RequestTimeoutTaskRunnble requestTimeoutTask = new RequestTimeoutTaskRunnble(requestTask, new RequestTaskStatusListener() {
@Override
public void statusListener(Object object) {
// do failure things
}
});
// 向线程池中添加一个任务
downloadPoolManager.addDownloadTask(requestTask,requestTimeoutTask);
}
一个例子是写完了,我们来看一看RequestTaskRunnble 和 RequestTimeoutTaskRunnble 吧,其实里面啥也没有,只是一个空的run()方法而已。
public class RequestTaskRunnble extends Thread {
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>/**
<span style="white-space:pre"> </span> * 线程的唯一标识,也就是url地址
<span style="white-space:pre"> </span> */
<span style="white-space:pre"> </span>private String taskName = "";
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>/**
<span style="white-space:pre"> </span> * 监听回调接口
<span style="white-space:pre"> </span> */
<span style="white-space:pre"> </span>private RequestTaskStatusListener requestListener = null;
<span style="white-space:pre"> </span>public RequestTaskRunnble(String taskName,RequestTaskStatusListener requestListener) {
<span style="white-space:pre"> </span>this.taskName = taskName;
<span style="white-space:pre"> </span>this.requestListener = requestListener;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>@Override
<span style="white-space:pre"> </span>public void run() {
<span style="white-space:pre"> </span>super.run();
<span style="white-space:pre"> </span>// test run
<span style="white-space:pre"> </span>int temp = 0;
<span style="white-space:pre"> </span>while(temp<100){
<span style="white-space:pre"> </span>temp ++;
<span style="white-space:pre"> </span>requestListener.statusListener(temp);
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>public String getFileId() {
<span style="white-space:pre"> </span>return taskName;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>public RequestTaskStatusListener getRequestListener(){
<span style="white-space:pre"> </span>return requestListener;
<span style="white-space:pre"> </span>}
}
RequestTimeoutTaskRunnble 监听 RequestTaskRunnble线程的状态。
public class RequestTimeoutTaskRunnble extends Thread {
/**
* 需要监控的任务对象
*/
private RequestTaskRunnble downloadTask = null;
/**
* 监听回调接口
*/
private RequestTaskStatusListener requestListener = null;
public RequestTimeoutTaskRunnble(RequestTaskRunnble downloadTask,RequestTaskStatusListener requestListener) {
this.downloadTask = downloadTask;
this.requestListener = requestListener;
}
@Override
public void run() {
super.run();
}
public String getFileId() {
return downloadTask.getFileId();
}
public RequestTaskStatusListener getRequestListener(){
return requestListener;
}
强调一下,如果你的work线程不需要做超时处理的话,可以直接这么写。至于为什么会有RequestTimeoutTaskRunnble,在实际开发中,会有很多需要超时处理的例子。
downloadPoolManager.addDownloadTask(requestTask,null);
当然,该线程池会提供停止线程池的方法。
// 停止线程池的方法 false 表示不再往线程池里添加线程,true表示立刻停止运行线程池里的所有线程。
// downloadPoolManager.shutdownDownloadTask(false);
downloadPoolManager.shutdownDownloadTask(true);
好了,只用是没问题了,我们来看最核心的类 DownloadPoolManager,这个类太长了,我就不贴出来了,附件会有的,这里我直接就把一些核心的东西贴出来吧。这里边主要包含两个核心类。
一个是线程管理类DownloadTaskManager,用来管理添加的线程,判断是否有重复的任务和取出任务。
/**
* 1.先执行
* 增加任务
* @param downloadTask:任务对象
*/
public void addDownloadTask(RequestTaskRunnble downloadTask, RequestTimeoutTaskRunnble downloadTimeoutTask) {
synchronized (downloadTasks) {
if (!isTaskRepeat(downloadTask.getFileId())) {
// 增加下载任务
Map<String, Object> map = new HashMap<String, Object>();
map.put("task", downloadTask);
map.put("timeoutTask", downloadTimeoutTask);
downloadTasks.addLast(map);
}
}
}
一个是线程池管理类DownloadTaskManagerThread,用来执行一个任务,停止线程池和设置线程池的一些配置信息。
while (!isStop) {
Map<String, Object> taskMap = downloadTaskManager.getDownloadTask();
System.out.println("taskMap = " + taskMap);
System.out.println("taskPool.isTerminated() = " + taskPool.isTerminated());
if (taskMap != null) {
RequestTaskRunnble downloadTask = (RequestTaskRunnble) taskMap.get("task");
RequestTimeoutTaskRunnble downloadTimeoutTask = (RequestTimeoutTaskRunnble) taskMap.get("timeoutTask");
taskPool.execute(downloadTask);
if(downloadTimeoutTask != null) {
timeoutTaskPool.execute(downloadTimeoutTask);
}
pollingCurrentCount = 0;
} else { // 如果当前未有downloadTask在任务队列中
try {
// 查询任务完成失败的,重新加载任务队列轮询,
Thread.sleep(SLEEP_TIME);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
pollingCurrentCount++;
if(pollingCount <= 0) {
downloadManager.shutdownDownloadTask(false);
} else if(pollingCount > 0 && pollingCurrentCount == pollingCount) {
downloadManager.shutdownDownloadTask(false);
} else {
continue;
}
}
}
好了,已经算是完事儿了,目前这个管理类没有提供任务的删除方法,有待优化,我会把一个完整的demo直接贴出来,供大家参考。
下载地址:http://download.csdn.net/download/u013003388/9296943