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

 import java.util.TimerTask;

 public class MsgTask extends TimerTask {
private long deltaTime; //时间增量,及任务执行等待时间
private MsgKey msgKey;
private MsgProcessor msgProcessor = new MsgProcessor(); public MsgTask(MsgKey msgKey,long deltaTime) {
super();
this.msgKey = msgKey;
this.deltaTime = deltaTime;
} public long getDeltaTime() {
return deltaTime;
} public void setDeltaTime(long deltaTime) {
this.deltaTime = deltaTime;
} public MsgKey getMsgKey() {
return msgKey;
} public void setMsgKey(MsgKey msgKey) {
this.msgKey = msgKey;
} @Override
public void run() {//等待时间到了以后,就执行
int index = msgKey.getIndex();
msgProcessor.dealOverTimeMsg(index);
MsgManager.removeMsgTask(msgKey);
this.cancel();
}
}

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

 import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer; import android.util.Log; public class MsgManager {
private static Timer timer = new Timer();
private static Map<MsgKey, MsgTask> msgTasks = Collections.synchronizedMap(new HashMap<MsgKey, MsgTask>()); public static void putMsgTask(MsgKey msgKey,MsgTask msgTask) {
synchronized (msgTasks) {
msgTasks.put(msgKey, msgTask);
}
} public static void startMsgTask(MsgKey msgKey,MsgTask msgTask) {
putMsgTask(msgKey, msgTask);
timer.schedule(msgTask, msgTask.getDeltaTime());
Log.d("zyr",""+msgKey.getIndex());
} public static MsgTask removeMsgTask(MsgKey msgKey) {
MsgTask msgTask = null;
synchronized (msgTasks) {
msgTask = msgTasks.remove(msgKey);
}
return msgTask;
} public static boolean stopMsgTask(MsgKey msgKey) {
MsgTask msgTask = removeMsgTask(msgKey);
if (msgTask != null){
msgTask.cancel();
return true;
}
return false;
}
}

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

 public class MsgKey {
private int index; public int getIndex() {
return index;
} public void setIndex(int index) {
this.index = index;
} @Override
public boolean equals(Object obj) {
if (obj instanceof MsgKey) {
MsgKey msgKey = (MsgKey) obj;
return this.index == msgKey.getIndex();
} else {
return false;
}
} @Override
public int hashCode() {
return String.valueOf(this.index).hashCode();
}
}

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

 public class MsgProcessor {

     /**
* 处理超时的消息
* @param index
*/
public void dealOverTimeMsg(int index){
switch (index) {
case 0:
loginOverTimeHandler();
break; default:
break;
}
} private void loginOverTimeHandler(){
//这里写处理方法
}
}

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

一个 Android 任务队列的实现的更多相关文章

  1. 用Kotlin创建第一个Android项目(KAD 01)

    原文标题:Create your first Android project using Kotlin (KAD 01) 作者:Antonio Leiva 时间:Nov 21, 2016 原文链接:h ...

  2. 一个android参考网站,工具+源码

    Android多渠道打包工具  https://github.com/wubo/apptools Android官方培训课程中文版(v0.9.4)  http://hukai.me/android-t ...

  3. 3.创建第一个android项目

    安卓开发学习笔记 1.安卓开发之环境搭建 2.SDK目录结构和adb工具及命令介绍 3.创建第一个android项目 1.打开Eclipse,选择File——>new——>others.. ...

  4. 创建一个Android项目

    当我们的eclipse安装了SDK后,点击Window-->Perference-->DDMS.eclipse界面立即转为DDMS界面. 这时,我们可以打开我们的服务端(安卓模拟器或者是我 ...

  5. 认识Activity,创建第一个android应用-Hello Word

    2016-04-05 配置好Java.eclipse和Android环境就花费了一天时间.下载SDK真是费了不少时间.现在终于找到解决SDK更新的好方法了(更新自己电脑上的hosts文件,就可以使用G ...

  6. Android开发自学笔记(Android Studio1.3.1)—2.开始第一个Android应用

    一.前言      使用Android Studio开发Android应用是一件非常简单的事情,因为它会帮你自动完成很多工作.本篇我们主要完成一个单击按钮在文本框显示当前时间的简单应用,借此来演示一下 ...

  7. android开发------第一个android程序

    好吧,现在我们就一起来写第一个android程序,看它带给了我们什么.sdk的使用和虚拟机的创建我就不说了.项目创建过程先略过,不太重要. 那第一个程序我们能学到什么知识呢?一起看吧.^-^ 在IDE ...

  8. 如何把一个android工程作为另外一个android工程的lib库

    http://zhidao.baidu.com/question/626166873330652844 一个工程包含另一个工程.相当于一个jar包的引用.但又不是jar包反而像个package 在网上 ...

  9. 一个android样本的过保护

    前段时间处理一个android样本,样本本身作用不大,但是加了保护,遂做一个过保护的记录 通过dex2jar将dex转为jar文件的时候发现无法成功,通过抛出的异常可知,此处MainActivity: ...

随机推荐

  1. poj3114Countries in War(缩点+DIJK)

    http://poj.org/problem?id=3114 缩点+DIJK 注意缩点之后有重边啊 floyd会TLE #include <iostream> #include<cs ...

  2. The Impact of Garbage Collection on Application Performance

    As we’ve seen, the performance of the garbage collector is not determined by the number of dead obje ...

  3. grep 同时满足多个关键字和满足任意关键字

    grep 同时满足多个关键字和满足任意关键字 ① grep -E "word1|word2|word3"   file.txt    满足任意条件(word1.word2和word ...

  4. 最小生成树(kruskal模版 模板)

    题目:http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=2144&cid=1186 #include<stdio.h> #incl ...

  5. poj2823

    这是一道题意简单,数据较大的题(喜闻乐见): 一开始可能会想到RMQ问题,ST,线段树都是O(nlogn),应该勉强能过(没试过): 由于这道题区间是滚动连续的,所以,可以使用单调队列! 以最小值为例 ...

  6. 【MooTools】

    MooTools a compact javascript frameworkhttp://mootools.net/docs/core 30天学会 MooTools 教学(1): 认识MooTool ...

  7. 新功能:Azure 负载平衡器的空闲超时现可配置了

    Yves Pitsch Azure 网络首席项目经理 我们很高兴地宣布,Azure负载平衡器现在可以为云服务和虚拟机提供可配置的 TCP空闲超时支持.要配置此功能,可以使用服务管理 API.Power ...

  8. Rman实现数据库迁移

    Rman实现数据库迁移(从库A迁移到库B)环境:服务器A:Oracle10g+AS3服务器B:Oracle10g+AS4准备工作: 1 在数据库B上建立与库A相同的目录结构(若由于磁盘空间等原因可以用 ...

  9. (1)java虚拟机概念和结构图

    java虚拟机解构图一 java虚拟机解构图二 java虚拟机结构图三 [1]类加载系统        --->负责从文件系统或网络中加载class信息,存放至方法区的内存空间[2]java堆  ...

  10. EF Code First 学习笔记:约定配置

    要更改EF中的默认配置有两个方法,一个是用Data Annotations(在命名空间System.ComponentModel.DataAnnotations;),直接作用于类的属性上面;还有一个就 ...