一个 Android 任务队列的实现

      最近在做Android项目时遇到这样一个问题:客户端向服务器请求数据,而在网络信号太差的情况下,数据迟迟不到,甚至丢失。服务器为了解决这个问题做了频繁的重发,android 客户端就会收到很多不想要的消息;或者因为消息回来太慢,用户已经失去耐心的去做别的操作了,而那个姗姗来迟的消息的到来就会让用户莫名其妙。
      如何有一个类,在向服务器发出请求的时候就向任务队列中添加一条任务,并启动,等待时间到了以后就丢弃这个任务;在等待时间内如果有相应的响应消息返回的时候,则停掉该任务就解决了这一难题了。
      下面是任务类:

 1 import java.util.TimerTask;
 2 
 3 public class MsgTask extends TimerTask {
 4     private long deltaTime;  //时间增量,及任务执行等待时间
 5     private MsgKey msgKey;
 6     private MsgProcessor msgProcessor = new MsgProcessor();
 7  
 8     public MsgTask(MsgKey msgKey,long deltaTime) {
 9         super();
10         this.msgKey = msgKey;
11         this.deltaTime = deltaTime;
12     }
13 
14     public long getDeltaTime() {
15         return deltaTime;
16     }
17 
18     public void setDeltaTime(long deltaTime) {
19         this.deltaTime = deltaTime;
20     }
21 
22     public MsgKey getMsgKey() {
23         return msgKey;
24     }
25 
26     public void setMsgKey(MsgKey msgKey) {
27         this.msgKey = msgKey;
28     }
29 
30     @Override
31     public void run() {//等待时间到了以后,就执行
32         int index = msgKey.getIndex();
33         msgProcessor.dealOverTimeMsg(index);
34         MsgManager.removeMsgTask(msgKey);
35         this.cancel();
36     }
37 }

为了方便对任务队列的管理,可以写一个任务管理类:

 1 import java.util.Collections;
 2 import java.util.HashMap;
 3 import java.util.Map;
 4 import java.util.Timer;
 5 
 6 import android.util.Log;
 7 
 8 public class MsgManager {
 9     private static Timer timer = new Timer();
10     private static Map<MsgKey, MsgTask> msgTasks = Collections.synchronizedMap(new HashMap<MsgKey, MsgTask>());
11 
12     public static void putMsgTask(MsgKey msgKey,MsgTask msgTask) {
13         synchronized (msgTasks) {
14             msgTasks.put(msgKey, msgTask);
15         }
16     }
17 
18     public static void startMsgTask(MsgKey msgKey,MsgTask msgTask) {
19         putMsgTask(msgKey, msgTask);
20         timer.schedule(msgTask, msgTask.getDeltaTime());
21         Log.d("zyr",""+msgKey.getIndex());
22     }
23 
24     public static MsgTask removeMsgTask(MsgKey msgKey) {
25         MsgTask msgTask = null;
26         synchronized (msgTasks) {
27             msgTask = msgTasks.remove(msgKey);
28         }
29         return msgTask;
30     }
31 
32     public static boolean stopMsgTask(MsgKey msgKey) {
33         MsgTask msgTask = removeMsgTask(msgKey);
34         if (msgTask != null){
35             msgTask.cancel();
36             return true;
37         }
38         return false;
39     }
40 }

任务需要一个标志,才能方便启动和结束,下面的MsgKey就是用来标记任务的实体类:

 1 public class MsgKey {
 2     private int index;
 3 
 4     public int getIndex() {
 5         return index;
 6     }
 7 
 8     public void setIndex(int index) {
 9         this.index = index;
10     }
11  
12     @Override
13     public boolean equals(Object obj) {
14         if (obj instanceof MsgKey) {
15             MsgKey msgKey = (MsgKey) obj;
16             return this.index == msgKey.getIndex();
17         } else {
18             return false;
19         }
20     }
21 
22     @Override
23     public int hashCode() {
24         return String.valueOf(this.index).hashCode();
25     }
26 }

当然,如果等待超时,一定要有相应的处理的:

 1 public class MsgProcessor {
 2  
 3     /**
 4      * 处理超时的消息
 5      * @param index
 6      */
 7     public void dealOverTimeMsg(int index){
 8         switch (index) {
 9         case 0:
10              loginOverTimeHandler();
11              break;
12 
13         default:
14              break;
15         }
16     }
17  
18     private void loginOverTimeHandler(){
19         //这里写处理方法
20     }
21 }

值得注意的是:如果需要把任务添加到任务队列后并立即执行,则用startMsgTask方法,结束这个任务时要用stopMsgTask方法,如果没有这个任务 stopMsgTask返回false;如果需要把任务添加到任务队列但不确定什么时候执行,则用putMsgTask方法,结束这个任务时就用removeMsgTask方法就可以了,如果没有这个任务removeMsgTask返回null。

原文地址:https://www.cnblogs.com/eustoma/p/4459104.html