zoukankan      html  css  js  c++  java
  • 一个 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。

  • 相关阅读:
    gearman管理工具GearmanManager的安装与使用
    php使用gearman进行任务分发
    centos7下的FastDFS5.09的安装与使用
    centos7下的glusterfs的安装与使用
    centos7下keepalived1.3.4安装与使用
    centos7下haproxy1.7的使用与配置
    centos7下apache2.4反向代理
    centos7下Redis3的安装与使用
    php使用fputcsv进行大数据的导出
    php新增的一些特性
  • 原文地址:https://www.cnblogs.com/eustoma/p/4459104.html
Copyright © 2011-2022 走看看