最近在做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。