最近在做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. 大四实习准备1_java构造器_android ListView

    2015-4-23 Java构造器 与类名同名;无返回值(void也不行);被不同的修饰符修饰是有区别的;当构造函数被private修饰时,只有本类可访问.其他类可以通过该类的get函数得到对象.如单 ...

  2. poj3041,poj2226

    二分匹配的灵活运用 3041还是比较好想的,考虑到横排/竖排射一枪就能搞定这一行/一列的所有点, 我们以行数为点集x,列数为点集y,在目标点(xi,yi)之间连一条边 这样最小射击次数=最小点覆盖(边 ...

  3. android MIPI屏 导航栏丢失

    /**************************************************************************** * android MIPI屏 导航栏丢失 ...

  4. UVA 1515 Pool construction 水塘(最大流,经典)

    题意: 给一个h*w的矩阵,每个格子中是'#'和'.'两个符号之一,分别代表草和洞.现在要将洞给围起来(将草和洞分离),每条边需花费b元(即将一个洞包起来需要4边,将2个连续的洞包起来需要6边,省了2 ...

  5. Spring中使用quartz插件实现定时任务

    第一步:导入架包 *spring3.2.3版本的架包将spring的各个功能模块给分开了,我们必须将Spring必须依赖的包导入上去 第二步:编写配置文件 <?xml version=" ...

  6. NopCommerce架构分析之五------Model绑定Action参数

    asp.net MVC中Action参数不只是一些基本类型,也支持实体参数.那么从客户端传来的数据如何映射或转换成实体对象呢?就是通过实体绑定类ModelBinder.此系列类在请求转化为后台Cont ...

  7. MessagePack介绍

    在项目中,服务端的人需要我研究messagepcak 进行数据的传输,对messagePack的了解就是传输的数据格式都是二进制,可以节省用户的流量,就因为这点 数据格式小,服务端决定采用msgpac ...

  8. Cloudera Manager安装

    安装环境: 系统:CentOS 6.3 64位 虚拟机:VMWare

  9. NOIP2003 传染病控制

    题四     传染病控制 [问题背景] 近来,一种新的传染病肆虐全球.蓬莱国也发现了零星感染者,为防止该病在蓬莱国 大范围流行,该国政府决定不惜一切代价控制传染病的蔓延.不幸的是,由于人们尚未完 全认 ...

  10. 2.1CUDA-Thread

    在HOST端我们会分配block的dimension, grid的dimension.但是对应到实际的硬件是如何执行这些硬件的呢? 如下图: lanuch kernel 执行一个grid. 一个Gri ...