Android定时器任务的几种实现方式
2016-11-07 16:41
525 查看
(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
结果:
(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只为静态分配一次内存,在加载类的过程中完成静态变量的内存分配,我们做如下修改就能解决上面的这个问题
(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就行了
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
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失效问题详解
- android 定时任务的几种实现方式
- Android定时器的几种实现方式
- Android 定时器实现的几种方式和removeCallbacks失效问题详解
- Android 定时器实现的几种方式和removeCallbacks失效问题详解
- Android 定时器实现的几种方式和removeCallbacks失效问题详解
- Android定时器实现的几种方式整理及removeCallbacks失效问题解决
- android中实现定时器的几种方式
- Android 定时器实现的几种方式和removeCallbacks失效问题详解
- Android 定时器实现的几种方式和removeCallbacks失效问题详解
- android 定时任务的几种实现方式
- android 实现定时任务的几种方式
- 【转】Android 定时器实现的几种方式和removeCallbacks失效问题详解--不错
- Android 定时器实现的几种方式和removeCallbacks失效问题详解
- Android之定时器实现的几种方式和removeCallbacks失效问题详解
- Android中几种定时任务的种实现方法
- Android中几种定时任务的种实现方法
- android实现视频播放的几种方式
- android中Button监听器的几种实现方式
- android中的定时器几种实现