定时任务

2019-03-11  本文已影响0人  俗人浮生

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

上一篇下一篇

猜你喜欢

热点阅读