最近在做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. 基于邻接矩阵的深度优先搜索(DFS)

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

  2. Birt时间参数添加My97日历控件

    首先,思路: 引用My97.js然后为时间参数的textbox添加onclick事件 1.将My97添加到项目中的webcontent目录下(如图:) 2.添加My97引用 在项目路径下找到该文件\w ...

  3. SharePoint 2013 入门教程--系列文章

    转:http://www.cnblogs.com/jianyus/p/3381415.html 以下文章是自己在学习SharePoint的过程中,不断积累和总结的博文,现在总结一个目录,分享给大家.这 ...

  4. 在MFC[转载]在MFC状态栏显示时间 状态栏显示时间

    原文:在MFC状态栏显示时间,谢小哈皮儿 c/c++ vc 在mfc状态栏显示时间,在VC的控件中有个Status bar可以在窗体状态栏中添加日期和时间.其实通过简单的代码,你就能创建一个有时钟显示 ...

  5. jdbc三种常见用法

    import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sq ...

  6. 总结1-JMeter压力测试

    考虑到测试最需要逻辑能力,所以今天开始慢慢写些东西,希望能自我锻炼下. 第一个课题是压力测试,会把我了解到的和百度的东西按我的思路整合一下 一 什么是压力测试 二 压力测试所需要关注的参数 三 怎么做 ...

  7. JS注入操作页面对象

    在用selenium webdriver 编写web页面的自动化测试代码时,有时对页面对象的操作需要通过js语句去执行,selenium本身就支持执行js,我们在代码中import org.openq ...

  8. dateline 在数据库中就是 整型字段。date函数是可以转换成可读日期的。

    返回数据中的dateline全部用date()函数转换后再返回,是要嵌套循环还是遍历,代码怎么写? //查询我的活动 function user_activity_info_by_uid($uid){ ...

  9. C# 调用Dll 传递字符串指针参(转)

    http://www.cnblogs.com/jxsoft/archive/2011/07/06/2099061.html

  10. Ngrok,一款可以帮助你展示网站和联网开发的工具

      使用Ngrok的目的就是为了可以让别人通过网络访问到自己本机上的项目 下面是一个简单的使用教程,详细的查看官网英文文档. 第一步: 登录官网:https://ngrok.com/   注册或者登录 ...