Android 定时器实现的几种方式和removeCallbacks失效问题详解
实现定时器有很多种方式,在这里我简单的介绍几种方式
(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秒钟打印一次日志。
package com.example.demoactivity; 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就行了
今天主要介绍这三种方法,写的不好的地方希望大家指出,谢谢!转自:http://blog.csdn.net/xiaanming/article/details/9011193
Android 定时器实现的几种方式和removeCallbacks失效问题详解的更多相关文章
- 【转】Android 定时器实现的几种方式和removeCallbacks失效问题详解--不错
原文网址:http://blog.csdn.net/xiaanming/article/details/9011193 实现定时器有很多种方式,在这里我简单的介绍几种方式 (1)使用Handler + ...
- Form_Form页面跳转的四种方式(open_form, call_form, new_form, fnd_function)详解(汇总)
2014-06-29 Created By BaoXinjian
- uni-app&H5&Android混合开发三 || uni-app调用Android原生方法的三种方式
前言: 关于H5的调用Android原生方法的方式有很多,在该片文章中我主要简单介绍三种与Android原生方法交互的方式. 一.H5+方法调用android原生方法 H5+ Android开发规范官 ...
- JAVA高级架构师基础功:Spring中AOP的两种代理方式:动态代理和CGLIB详解
在spring框架中使用了两种代理方式: 1.JDK自带的动态代理. 2.Spring框架自己提供的CGLIB的方式. 这两种也是Spring框架核心AOP的基础. 在详细讲解上述提到的动态代理和CG ...
- Android开发之手势滑动(滑动手势监听)详解
Android开发之手势滑动(滑动手势监听)详解 在Android应用中,经常需要手势滑动操作,比如上下滑动,或左右方向滑动,处理手势滑动通常有两种方法:一种是单独实现setOnTouchListen ...
- jQuery插件开发的两种方法及$.fn.extend的详解(转)
jQuery插件开发的两种方法及$.fn.extend的详解 jQuery插件开发分为两种:1 类级别.2 对象级别,下面为大家详细介绍下 jQuery插件开发分为两种: 1 类级别 类级别你可以 ...
- Android Studio一直显示Building“project name”Gradle project info问题详解
关注我,每天都有优质技术文章推送,工作,学习累了的时候放松一下自己. 本篇文章同步微信公众号 欢迎大家关注我的微信公众号:「醉翁猫咪」 Android Studio一直显示 Building&quo ...
- Android 更新UI的几种方式
1.Activity的 runOnUiThread textView = (TextView) findViewById( R.id.tv ); new Thread(new Runnable() { ...
- Android请求服务器的两种方式--post, get的区别
android中用get和post方式向服务器提交请求_疯狂之桥_新浪博客http://blog.sina.com.cn/s/blog_a46817ff01017yxt.html Android提交数 ...
随机推荐
- Designing Evolvable Web API with ASP.NET 随便读,随便记 “The Internet,the World Wide Web,and HTTP”——HTTP
HTTP 我们将只聚焦在于与创建 Web APIs有关的部分. HTTP 是信息系统中的一个应用层协议,是Web的支柱. 其原先由 Berners-Lee, Roy Fielding 和 Henrik ...
- nodejs API笔记
一.URL 涉及到的方法 1.parse():解析地址 2.format():生成地址 3.resolve(from,to):组合成地址 举例说明: url.parse('http://baidu.c ...
- RStudio Keyboard Shortcuts
Console Description Windows & Linux Mac Move cursor to Console Ctrl+2 Ctrl+2 Clear console Ctrl+ ...
- delphi 单例模式实现
unit Unit2; interface uses System.SysUtils; type { TSingle } TSingle = class(TObject) private FStr: ...
- Failed to allocate the network(s), not rescheduling
Failed to allocate the network(s), not rescheduling 在计算节点的/etc/nova/nova.conf中添加下面两句 #Fail instance ...
- HTTPS 升级指南
上一篇文章我介绍了 HTTP/2 协议 ,它只有在 HTTPS 环境才会生效. 为了升级到 HTTP/2 协议,必须先启用 HTTPS.如果你不了解 HTTPS 协议(学名 TLS 协议),可以参考我 ...
- Java多线程编程之同步器
同步器 为每种特定的同步问题提供了解决方案 Semaphore Semaphore[信号标:旗语],通过计数器控制对共享资源的访问. 测试类: package concurrent; import c ...
- linux中vi编辑器
vi编辑器,通常称之为vi,是一种广泛存在于各种UNIX和Linux系 统中的文本编辑程序.它的功能十分强大,但是命令繁多,不容易掌握,它可以执行输出.删除.查找.替换.块操作等众多文本操作,而且用户 ...
- HDU 1078 FatMouse and Cheese (记忆化搜索)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1078 老鼠初始时在n*n的矩阵的(0 , 0)位置,每次可以向垂直或水平的一个方向移动1到k格,每次移 ...
- presentedViewController 和 presentingViewController 以及 dismissViewControllerAnimated 的使用
在日常的开发中,多控制器之间的跳转除了使用push的方式,还可以使用 present的方式,present控制器时,就避免不了使用 presentedViewController.presenting ...