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

    对于这种题很容易看出是费用流吧…… 但这道题不容易建模: 首先是怎么表示目标状态和其实状态,看起来有黑有白很复杂 但实际上,不难发现,白色格子没什么用,起决定作用的是黑格子 也就是我们可以把问题简化: ...

  2. 关于C#控制台传递参数和接收参数

    前言: 写了这么久程序,今天才知道的一个基础知识点,就是程序入口 static void Main(string[] args) 里的args参数是什么意思 ?惭愧... 需求: 点击一个button ...

  3. Django提供后台接口的跨域问题

    --> Django跨域 当使用Django仅用来开发后端接口,为前端提供JSON数据的时候,不可避免的要接受前端的POST请求.虽然Django以其强大易用的特定使用很广泛,但在跨域问题上却让 ...

  4. 手动启动angular

    关于手动启动 angular 的问题 angular核心原理解析1:angular自启动过程 angular.element(document).ready(function() { angular. ...

  5. Maven配置文件Pom.xml详解

    <project xmlns="http://maven.apache.org/POM/4.0.0 "      xmlns:xsi="http://www.w3. ...

  6. SQL LEFT JOIN 关键字

    SQL LEFT JOIN 关键字 LEFT JOIN 关键字会从左表 (table_name1) 那里返回所有的行,即使在右表 (table_name2) 中没有匹配的行. LEFT JOIN 关键 ...

  7. iOS开发中提交带有中文或特殊字符串的参数

    iOS开发中,与后台进行数据交换是一个很常见的场景. 在web开发中,对于我们提交的地址,浏览器会负责进行decode,但是在ios中,必须要自己手动来实现.否则我们拼接出的网址在包括中文.特殊字符串 ...

  8. Ext入门学习系列(三)复杂自定义窗体

    通过前2节的学习,基本掌握了Ext的语法和运行原理,可以作出一些简单的应用.本节我们一起来完成复杂点的对话框操作,因为在实际项目中经常要用到确认对话框等多种操作,然后根据客户的选择作出不同的响应. 一 ...

  9. HDU4614 Vases and Flowers

    http://acm.hdu.edu.cn/showproblem.php?pid=4614 HDU 4614 Vases and Flowers (2013多校第二场线段树) // #pragma ...

  10. HDU 3289 Cat VS Dog (二分匹配 求 最大独立集)

    题意:每个人有喜欢的猫和不喜欢的狗.留下他喜欢的猫他就高心,否则不高心.问最后最多有几个人高心. 思路:二分图求最大匹配 #include<cstdio> #include<cstr ...