一、前言:
在做android开发的时候少不了会用到定时器的功能,而每次使用都是需要思考回顾一番。而缺少对定时器完整方法的把握。文本主要记录总结:
- 梳理android中常用的几种定时器以及使用方法。
- 对比各自的优缺点
二、定时器类型:
方式一:通过Handler.postDelayed()
/**
* 倒计时方式一 通过Handler.postDelayed()
*/
private void startTimer() {
Log.d("TimerActivity ", " 倒计时3s开始");
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
long threadId = Thread.currentThread().getId();
long mainThreadId = Looper.getMainLooper().getThread().getId();
if(threadId == mainThreadId){
// 回调在主线程
Log.d("TimerActivity ", "回调在主线程!");
}else{
Log.d("TimerActivity ", "回调在非主线程!");
}
}
}, 3000);
}
方式二:通过Timer.schedule()
/**
* 方式2 通过Timer.schedule()
*/
private void startTimer2(){
Log.d("TimerActivity ", " 倒计时3s开始");
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
// 回调在主线程
long threadId = Thread.currentThread().getId();
long mainThreadId = Looper.getMainLooper().getThread().getId();
if(threadId == mainThreadId){
Log.d("TimerActivity ", "回调在主线程!");
}else{
Log.d("TimerActivity ", "回调在非主线程!");
}
}
},3000);//延时1s执行
}
方式三:通过阻塞线程Thread.sleep(3000)
private void startTimer3(){
Log.d("TimerActivity ", " 倒计时3s开始");
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(3000);//延时3s
//do something
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
这种方式在大量使用到定时器的地方不宜直接使用。
方式四:通过系统封装好的CountDownTimer
/**
* 使用 CountDownTimer
*/
private void startTimer4(){
CountDownTimer countDownTimer = new CountDownTimer(3000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
// 每次1000毫秒 执行一次
Log.d("TimerActivity ", "millisUntilFinished:"+millisUntilFinished);
}
@Override
public void onFinish() {
// 执行完毕
Log.d("TimerActivity ", "onFinish:执行完毕!");
}
};
countDownTimer.start();
}
方式五:通过第三方类库RxJava Timer()
Observable.timer(20, TimeUnit.SECONDS)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<Long>() {
@Override
public void accept(Long aLong) throws Exception {
Log.d("App","恢复Icon");
switchAppIcon(false);
}
});
方式六:通过线程池 ScheduledThreadPoolExecutor
private ScheduledThreadPoolExecutor mThreadPoolExecutor;
/**
* 使用 ScheduledThreadPoolExecutor
*/
private void startTimer5(){
if (mThreadPoolExecutor != null) {
mThreadPoolExecutor.shutdownNow();
}
mThreadPoolExecutor = new ScheduledThreadPoolExecutor(1);
// 初始化 3秒后执行,以后每5秒 执行一次,运行在 非主线程
mThreadPoolExecutor.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
Log.d("TimerActivity ", "ScheduledThreadPoolExecutor:执行!");
long threadId = Thread.currentThread().getId();
long mainThreadId = Looper.getMainLooper().getThread().getId();
if(threadId == mainThreadId){
Log.d("TimerActivity ", "回调在主线程!");
}else{
Log.d("TimerActivity ", "回调在非主线程!");
}
}
}, 3000, 5000, TimeUnit.MILLISECONDS);
}
三、总结:
以上就是几种常见的定时器方法,当然还有其他的一些方式,以后有时间遇到再补充完善。
还有就是对比每种定时器的优缺点以及底层原理,本文也没来得及涉及。
个人比较喜欢Handler.postDelayed() 和RxJava 的timer()方法。