转载:http://blog.csdn.net/xiaanming/article/details/9011193

实现定时器有很多种方式,在这里我简单的介绍几种方式

实现定时器有很多种方式,在这里我简单的介绍几种方式

(1)使用Handler + Runnable的方式

Handler handler = new Handler();
Runnable runnable = new Runnable() {
@Override
public void run() {
//你要做的事
//......
System.out.println(Thread.currentThread().getName());
handler.postDelayed(runnable, 1000);
}
};

然后调用handler.post(runnable);就能启动定时器,这里是每隔1s打印线程名字,从打印中我们可以知道,他并没有另开线程,而是运行在UI线程当中,当你要取消定时器的时候,只需要调用handler.removeCallbacks(runnable)就可以了。

上面中有一个问题,有时候你会发现removeCallbacks有时候会失效,不能从消息队列中移除,看下面的demo

图:两个按钮,一个将Runnable加到消息队列中,一个将Runnable从消息队列中移除。该Runnable每1秒钟打印一次日志。

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;  public class TimerActivity extends Activity{  Handler handler = new Handler();  Runnable runnable = new Runnable() {  @Override  public void run() {  System.out.println("update...");  handler.postDelayed(runnable, 1000);  }  };  @Override  protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.timer);  Button mButtonStart = (Button) findViewById(R.id.button1);  Button mButtonStop = (Button) findViewById(R.id.button2);  mButtonStart.setOnClickListener(new OnClickListener() {  @Override  public void onClick(View v) {  handler.post(runnable);  }  });  mButtonStop.setOnClickListener(new OnClickListener() {  @Override  public void onClick(View v) {  handler.removeCallbacks(runnable);  }  });  }  }

结果:
(1)start –>  输出 –> stop–> 停止输出
(2)start –> 输出 –>  Background –> Front –> stop->继续输出

当Activity进入后台运行后再转入前台运行,removeCallbacks无法将updateThread从message queue中移除。
这是为什么呢?
在Activity由前台转后台过程中,线程是一直在运行的,但是当Activity转入前台时会重新定义Runnable runnable;也就是说此时从message queue移除的runnable与原先加入message queue中的runnable并非是同一个对象。如果把runnable定义为静态的则removeCallbacks不会失效,对于静态变量在内存中只有一个拷贝(节省内存),JVM只为静态分配一次内存,在加载类的过程中完成静态变量的内存分配,我们做如下修改就能解决上面的这个问题

    static Handler handler = new Handler();  static Runnable runnable = new Runnable() {  @Override  public void run() {  System.out.println("update...");  handler.postDelayed(runnable, 1000);  }  };  

(2)使用Timer的方式

Timer timer = new Timer();
timer.schedule(new TimerTask() {  @Override  public void run() {  System.out.println("update....");  }
}, 0, 1000);

上面的每一秒打印语句,run方法是运行在子线程,不能直接在里面更新UI操作,这里需要注意下,取消的话调用timer.cancel()就能移除任务了

(3)采用Handle与线程的sleep(long )方法

1.定义一个Handler类,用于处理接受到的Message

Handler handler = new Handler() {  public void handleMessage(Message msg) {  super.handleMessage(msg);  System.out.println("update...");  }  

2.新建一个实现Runnable接口的线程类,用一个boolean 来控制线程开始和结束  boolean isLive = true如下:

    public class MyThread implements Runnable {  @Override  public void run() {  while (isLive) {  try {  Thread.sleep(1000);// 线程暂停1秒,单位毫秒  Message message = new Message();  message.what = 1;  handler.sendMessage(message);// 发送消息  } catch (InterruptedException e) {  e.printStackTrace();  } }  }  }  

3.在需要启动线程的地方加入下面语句

new Thread(new MyThread()).start();

4.取消的话将isLive设置为false就行了

Android之定时器实现的几种方式和removeCallbacks失效问题详解相关推荐

  1. Android 定时器实现的几种方式和removeCallbacks失效问题详解

    实现定时器有很多种方式,在这里我简单的介绍几种方式(1)使用Handler + Runnable的方式[java] view plain copy 在CODE上查看代码片派生到我的代码片Handler ...

  2. 进程间通信有哪几种方式?进程间通信的方法详解

    进程间通信有哪几种方式?不同进程之间是会进行相互传播或交换信息的,很多伙伴都很好奇,各进程之间是通过什么介质进行通信的呢?今天小编就给大家科普下进程间通信的方法. 前言: 进程间通信(IPC,Inte ...

  3. android asynctask源码分析,Android通过Handler与AsyncTask两种方式动态更新ListView(附源码)...

    本文实例讲述了Android通过Handler与AsyncTask两种方式动态更新ListView的方法.分享给大家供大家参考,具体如下: 有时候我们需要修改已经生成的列表,添加或者修改数据,noti ...

  4. android xpath解析xml,Android 中处理 XML 的四种方式-DOM

    Android 中处理 XML 的几种方式连载中,我们就不介绍合成 XML 了,因为合成 XML 可以直接拼接字符串,虽然看起很不高大上,但却很有效.我们主要介绍如何取 XML 中的值. 适用 DOM ...

  5. Android点击图片随机,android 设置图片随机出现-两种方式

    android 设置图片随机出现-两种方式, 第一种方式:得到图片对应的Drawable实例,通过setImageDrawable(drawable)实现 //ImageView对应的id ivBg ...

  6. Android中播放音乐的几种方式

    Android中播放音乐的几种方式 前言 前几天一直在研究RxJava2,也写了记录了几篇博客,但因为工作任务原因,需要研究音频相关的知识,暂时放下Rxjava,本文的demo中,MediaPalye ...

  7. android打开另外的app两种方式,内置到自己本身的app,重新打开app,

    android打开另外的app两种方式,内置到自己本身的app空间,重新打开app空间, 目录 1.内置到自己本身的app空间, 2.重新打开app空间, 1.内置到自己本身的app空间, 被打开的a ...

  8. 【Android】播放音频的几种方式介绍

    转自:u013366008的博客  https://blog.csdn.net/u013366008/article/details/76577372 Android中播放音乐的几种方式 前言 前几天 ...

  9. Android页面数据传递的两种方式

    在android中实现页面中数据的传递有两种方式: 1:第一种数据传递的方式是通过inputExtra方法来进行数据的传递的 2:第二中方法是通过bundle的方法来实现数据的传递的 接下来我们首先来 ...

最新文章

  1. 兴义网站服务器存储,兴义ipfs分布式存储操作系统
  2. 网络营销外包——网络营销外包公司如何做好电子商务网站优化?
  3. 学习笔记:文本过滤_____unix 下的通配符
  4. 隐藏马尔科夫模型HMM
  5. php面向对象魔术方法,PHP面向对象中的魔术方法
  6. 找出数组的最大公约数
  7. centos 安装 lua运行环境   非yum安装
  8. 沈大海38节jquery强化教程2016视频下载
  9. 如何把XPS格式文档转换为PDF?
  10. 什么查重软件比较好用?
  11. Fedora修复grub2启动项grub rescue
  12. 高德地图marker添加属性、更换icon图标
  13. JavaScript如何截取指定位置的字符串
  14. xp桌面上的计算机管理,如何解决WinXP系统开机桌面变白显示恢复Active Desktop的问题?...
  15. 极米、当贝、海信,争抢智能投影蛋糕
  16. 二十、D3D12学习笔记——环境光遮蔽
  17. C语言给出点坐标进行克里金插值,Arcgis笔记之克里金插值——求助surfer8.0
  18. CIE LAB色差公式与 CIE DE 2000色差公式计算类
  19. 易语言c s 上传多张图片,hbuilder如何上传多张图片?
  20. Android 有盟分享组件开发—微信未知错误 1

热门文章

  1. 实现多租户系统的一点思考
  2. 运维小姐姐说这篇Consul集群和ACL配置超给力(保姆级)
  3. 微服务技术栈及分享计划
  4. 了解一下HTTP1.1 Pipelining技术
  5. WPF开源控件扩展库 - MaterialDesignExtensions
  6. 揭秘!微软 Build 2020 开发者大会将启,邀您共赴线上新旅程
  7. [原]排错实战——使用process explorer替换任务管理器
  8. .NET Core 3.0 使用Nswag生成Api文档和客户端代码
  9. 30分钟无坑部署K8S单Master集群
  10. .NET Core使用NPOI导出复杂Word详解