当前位置: 移动技术网 > IT编程>移动开发>Android > Android定时器实现的几种方式整理及removeCallbacks失效问题解决

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

2019年07月24日  | 移动技术网IT编程  | 我要评论

新郑龙湖镇邮编,辽宁男篮赛程表,东南卫视官网

实现定时器有很多种方式,在这里我简单的介绍几种方式
(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秒钟打印一次日志。
复制代码 代码如下:

<span style="font-family: courier new">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);
}
});
}

}</span><span style="font-family: georgia, 'times new roman', times, san-serif">
</span>

结果:
(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就行了
今天主要介绍这三种方法,写的不好的地方希望大家指出,谢谢!

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网