`
阿尔萨斯
  • 浏览: 4417163 次
社区版块
存档分类
最新评论

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就行了

今天主要介绍这三种方法,写的不好的地方希望大家指出,谢谢!


分享到:
评论

相关推荐

    Android定时器实现的几种方式整理及removeCallbacks失效问题解决

    本篇文章主要探讨了两种使用Handler + Runnable的方式实现定时器,并针对`removeCallbacks()`失效的问题进行了分析。 首先,我们来看第一种实现定时器的方法。创建一个Handler对象并实例化一个Runnable,然后在...

    [代码】android定时器的三种实现方式

    本文将详细介绍三种常用的Android定时器实现方式及其具体应用场景。 #### 一种:采用Handler与线程的`sleep(long)`方法 这种方法主要是通过创建一个新的线程,并在该线程中使用`Thread.sleep()`方法来实现延时操作...

    Android定时器功能实现方法

    本文将详细介绍Android中如何实现定时器功能,包括两种主要的定时机制:`Handler`与`AlarmManager`。 一、基于Handler的定时器 `Handler`是Android消息处理机制的一部分,它可以配合`Looper`和`Message`实现延时或...

    Android中定时器的3种实现方法

    在Android开发中,定时任务的实现对于应用的功能扩展至关重要,比如自动刷新数据、倒计时、动画帧更新等。常见的实现方法有三种:...在实际开发中,通常根据项目需求和性能优化的考虑来选择最适合的定时器实现方式。

    andriod studio 定时器启动显示和停止的例子

    首先,我们需要了解Android中的定时器主要分为两种:`java.util.Timer`和`android.os.Handler`。在这个例子中,我们可能会使用到`Handler`来实现定时任务,因为它更适用于UI线程的更新。 1. **创建项目与布局**: ...

    android平台定时器介绍

    在Android平台上,定时任务的实现方式多样,主要目的是在特定时间点或周期性地执行某项操作。本文将详细介绍三种常见的Android定时器机制及其使用区别。 首先,我们来看第一种方式,即通过Handler与线程的`sleep...

    Android实现定时器的3种方法

    总之,理解并掌握这些定时器实现方式对Android开发者来说非常重要,因为它们在各种场景下都能发挥关键作用,如定期检查网络状态、执行后台任务或实现动画效果等。选择合适的方法可以提高程序性能和用户体验。

    android demo,使用Runnable和Handler的特性实现每个3s的定时器

    在Android开发中,`Runnable`和`Handler`是两种常用且关键的组件,它们在创建异步任务和处理UI更新方面发挥着重要作用。本示例的`android demo`旨在演示如何利用`Runnable`和`Handler`来实现一个每3秒执行一次的任务...

    基于Android中实现定时器的3种解决方法

    "基于Android中实现定时器的3种解决方法" Android中实现定时器的3种解决方法是Android开发中非常重要的技术之一。在Android开发中,定时器一般有以下3种实现方法:一、采用Handler与线程的sleep(long)方法;二、...

    Android定时器和Handler用法实例分析

    在Android开发中,定时任务和线程间的通信是常见的需求,本实例主要讲解了如何使用Android的定时器(Timer)以及结合Handler来实现定时任务和更新UI。下面将详细阐述这些知识点。 首先,Android中的定时器(Timer)...

    定时器理论

    android 中的定时器机制是指在 Android 系统中实现定时任务的方法,主要有三种实现方式:Handler 与线程的 sleep(long) 方法、Handler 的 postDelayed(Runnable, long) 方法、Handler 与 Timer 及 TimerTask 结合的...

    在android中使用定时器的方法

    在实际开发中,可以根据具体需求选择适合的定时器实现方式。Handler与线程的sleep方法简单但不够精确,Handler的postDelayed方法易于理解和使用,而Handler与Timer及TimerTask的结合则提供了更精确的定时控制。需要...

    Android实现一种简易的Banner效果

    `ViewPager`是Android SDK提供的一种用于在多个页面间滑动切换的组件,它允许用户左右滑动查看不同的页面,非常适合用来实现轮播图效果。在我们的Banner项目中,每个广告图片将被视为一个页面。 要使用`ViewPager`...

    Android----线程实现图片移动

    在Android开发中,图片动态...通过分析和学习这个示例,你可以更好地理解和掌握如何在Android中利用线程实现图片的动态效果。在实际开发中,可以根据具体需求进行调整,例如添加动画的缓动函数以实现更平滑的移动效果。

    android实现秒表功能

    在Android平台上实现秒表功能是一项常见的任务,它涉及到对时间的精确控制以及用户界面的交互设计。本篇文章将深入探讨如何使用Android SDK来构建这样一个功能,包括设置计时时间、开始、暂停和停止操作。 首先,...

    Android简单计时器实现

    这个项目适合初学者学习和理解Android计时器的实现方式,也可以根据自己的需求进行修改以适应不同的项目需求。 首先,我们需要了解Android中常用的两种计时器:`java.util.Timer` 和 `android.os.Handler`。在这个...

    Android实现轮播图Banner。包括自动播放,手动滑动。

    本教程将详细讲解如何在Android中实现一个功能完善的轮播图,包括自动播放和手动滑动功能。 首先,我们需要了解`ViewPager`,它是Android SDK提供的一种用于展示可滑动页面的视图。`ViewPager`可以与适配器...

Global site tag (gtag.js) - Google Analytics