一個 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。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM