Android中执行定时任务也是很常见的需求,今天我们就来实现一个最简单的定时任务:从1到10每隔1秒进行数数,实现方案有:(1)Handler (2)Timer (3)RxJava(4)ExecutorService(5)Alarm,直接上代码
/**
* 定时任务
*/
public class MyTimerTask {
private static Long count=0L;
public static void useHandler(){
LogUtil.loge("使用Handler");
final HandlerThread handlerThread=new HandlerThread("myThread");
handlerThread.start();
final Handler handler=new Handler(handlerThread.getLooper());
//final Handler handler=new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
if(count<10){
count++;
LogUtil.loge("count: " + count);
handler.postDelayed(this,1000);
}else {
LogUtil.loge("当前线程:"+Thread.currentThread().getName());
handlerThread.quit();//释放Looper//停止任务
}
}
},1000);
}
public static void useTimer(){
LogUtil.loge("使用Timer");
final Timer timer=new Timer();
TimerTask timerTask=new TimerTask() {
@Override
public void run() {
if(count<10){
count++;
LogUtil.loge("count: " + count);
}else {
//LogUtil.loge("如果要开始下一轮任务,会报错的");
//timer.schedule(this,1000,2000);//执行同一个TimerTask不行
timer.cancel();//停止任务
}
}
};
timer.schedule(timerTask,3000,1000);
//执行新的TimerTask可以
timer.schedule(new TimerTask() {
@Override
public void run() {
LogUtil.loge("执行新任务完毕!");
}
},6000);
}
public static void useExecutorService(){
final ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
if(count<10){
count++;
LogUtil.loge("count: " + count);
}else {
scheduledExecutorService.shutdown();//关闭线程池
}
}
},0,1,TimeUnit.SECONDS);
}
public static void useRxJava1(){
LogUtil.loge("使用RxJava");
Disposable disposable = Observable.intervalRange(0, 10, 5, 1, TimeUnit.SECONDS)
.map(new Function<Long, Long>() {
@Override
public Long apply(Long aLong) throws Exception {
return aLong + 1;
}
})
.subscribe(new Consumer<Long>() {
@Override
public void accept(Long count) throws Exception {
LogUtil.loge("count: " + count);
}
});
//disposable.dispose();//停止任务
}
public static void useRxJava2(){
LogUtil.loge("使用RxJava");
final CompositeDisposable compositeDisposable=new CompositeDisposable();
Observable.create(new ObservableOnSubscribe<Long>() {
@Override
public void subscribe(ObservableEmitter<Long> emitter) throws Exception {
if (emitter.isDisposed()||count==10) {
return;
}
emitter.onNext(++count);
emitter.onComplete();
}
}).delay(1,TimeUnit.SECONDS,true)// 设置delayError为true,表示出现错误的时候也需要延迟进行通知,达到无论是请求正常还是请求失败,都是1s后重新订阅,即重新请求。
.repeat()// repeat保证请求成功后能够重新订阅
.retry() // retry保证请求失败后能重新订阅
.subscribe(new Observer<Long>() {
@Override
public void onSubscribe(Disposable d) {
compositeDisposable.add(d);
}
@Override
public void onNext(Long aLong) {
LogUtil.loge("count: " + aLong);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
//compositeDisposable.clear();//停止任务
}
}
之所以写这一篇,也是因为两次面试中都被问到了,一次是问了Timer相关的,说真的之前Timer用得不多,有点懵。说到Timer,请注意一下上面笔者中注释掉的代码,运行会报以下异常:
java.lang.IllegalStateException: TimerTask is scheduled already
所以,对于Timer来说,它不能重复执行某任务,若在某个任务执行/取消之后,再次执行则会抛出一个IllegalStateException异常。
Timer相关的知识详情请参考:
https://www.cnblogs.com/benhero/p/4521727.html
https://www.cnblogs.com/xiaotaoqi/p/6874713.html
另一次是问了一个自定义控件中的定时任务,我说用Handler实现的,然而面试官问为什么不用RxJava呢?那会我才知道,原来RxJava也可以用来做定时任务,请原谅我一直用RxJava只是单纯滴与Retrofit配合使用而已,其实RxJava功能很是强悍,N多个操作符可供使用,详情可参考:
http://www.jcodecraeer.com/a/chengxusheji/java/2017/0731/8315.html
网友评论