Android计时常用的7种方式

以下计时方式都是Android中常见的计时方式,现总结如下:

1.timer、timertask配合handler计时

2.countdowntimer计时

3.handler精确计时方式

4.handler普通循环方式

5.ScheduleExecuteService定时

6.AlarmManager定时

7.rxJava计时

实现效果图如下:

Android计时常用的7种方式_第1张图片

下面配合具体代码详细介绍上述计时方式:

1.timer、timertask配合handler计时

实现方式:使用timer.schedule实现任务延迟,定时执行,timerTask实现的是Runnable,从timerTask中抛出的任务交给Handler执行即可:

// timer timerTask
    private int minute = 1;//这是分钟
    private int second = 1;//这是分钟后面的秒数。这里是以30分钟为例的,所以,minute是30,second是0
    private TextView timeView1;
    private Button btn_stop1;
    private Button btn_start1;
    private Timer timer;
    private TimerTask timerTask;

    private void startMethod1() {
        //防止多次点击开启计时器
        if (timer != null) {
            timer.cancel();
            timer = null;
        }
        if (timerTask != null) {
            timerTask = null;
        }


        timerTask = new TimerTask() {

            @Override
            public void run() {
                Message msg = new Message();
                msg.what = 0;
                handler.sendMessage(msg);
            }
        };

        timer = new Timer();
        timer.schedule(timerTask, 0, 1000);
    }

从timer中抛出的消息,在handler中执行,这个handler就是对时间的格式化,输出01:29的格式:

//这是接收回来处理的消息
    private Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            if (minute == 0) {
                if (second == 0) {
                    timeView1.setText("Time out !");
                    if (timer != null) {
                        timer.cancel();
                        timer = null;
                    }
                    if (timerTask != null) {
                        timerTask = null;
                    }
                } else {
                    second--;
                    if (second >= 10) {
                        timeView1.setText("0" + minute + ":" + second);
                    } else {
                        timeView1.setText("0" + minute + ":0" + second);
                    }
                }
            } else {
                if (second == 0) {
                    second = 59;
                    minute--;
                    if (minute >= 10) {
                        timeView1.setText(minute + ":" + second);
                    } else {
                        timeView1.setText("0" + minute + ":" + second);
                    }
                } else {
                    second--;
                    if (second >= 10) {
                        if (minute >= 10) {
                            timeView1.setText(minute + ":" + second);
                        } else {
                            timeView1.setText("0" + minute + ":" + second);
                        }
                    } else {
                        if (minute >= 10) {
                            timeView1.setText(minute + ":0" + second);
                        } else {
                            timeView1.setText("0" + minute + ":0" + second);
                        }
                    }
                }
            }
        }

    };

当然,上述方法可以使用String.format()简化成一行,完成时间的格式化输出:

private String formatTime2(long seconds) {
        return String.format(" %02d:%02d", seconds / 60, seconds % 60);
    }

2.countdowntimer计时

由于countDownTimer本身是由handler实现的,其计时是有误差的,简单用法如下,如何屏蔽掉计时误差,请参考handler实现精确计时的两种方式 https://blog.csdn.net/cpcpcp123/article/details/88542113:

    private void startMethod2() {
        countDownTimer.start();

    }

/**
     * 第一个参数表示总时间,第二个参数表示间隔时间。意思就是每隔一秒会回调一次方法onTick,然后10秒之后会回调onFinish方法
     */
    private CountDownTimer countDownTimer = new CountDownTimer(1000 * 100, 1000) {
        @Override
        public void onTick(long millisUntilFinished) {
            //秒转化成 00:00形式一
//            timeView2.setText(formatTime1(millisUntilFinished) + "");

            //秒转化成 00:00形式二
            timeView2.setText(formatTime2(millisUntilFinished / 1000));
            Log.e("hehehe ", millisUntilFinished + " ");
        }

        @Override
        public void onFinish() {

        }
    };

3.handler精确计时方式

    private void startMethod3() {
        mCalHandler.post(mTicker);
    }

    /**
     * 精确修正时间
     */
    private Handler mCalHandler = new Handler(Looper.getMainLooper());
    private final Runnable mTicker = new Runnable() {
        public void run() {
            long now = SystemClock.uptimeMillis();
            long next = now + (1000 - now % 1000);
            mCalHandler.postAtTime(mTicker, next);
            timeView3.setText(next + "");
        }
    };

4.handler普通循环方式

相关内容可参看:https://blog.csdn.net/ithomer/article/details/6903084

    /**
     * 通过Handler延迟发送消息的形式实现定时任务。
     */
    public static final int CHANGE_TIPS_TIMER_INTERVAL = 1000;
    private Handler mChangeTipsHandler = new Handler(Looper.getMainLooper());
    int i = 1;
    private void startMethod4() {
        Runnable mChangeTipsRunnable = new Runnable() {
            @Override
            public void run() {
                timeView4.setText(i++ + "handler");
                mChangeTipsHandler.postDelayed(this, CHANGE_TIPS_TIMER_INTERVAL);
            }
        };

        mChangeTipsHandler.post(mChangeTipsRunnable);
    }

5.ScheduleExecuteService定时

/**
     *  ScheduledExecutorService
     *  ScheduledExecutorService是从JDK1.5做为并发工具类被引进的,存在于java.util.concurrent,这是最理想的定时任务实现方式。
     *  相比于上面两个方法,它有以下好处:

     *  相比于Timer的单线程,它是通过线程池的方式来执行任务的,所以可以支持多个任务并发执行 ,而且弥补了上面所说的Timer的缺陷
     *  可以很灵活的去设定第一次执行任务delay时间
     *  提供了良好的约定,以便设定执行的时间间隔
     */
private ScheduledExecutorService scheduledExecutor5 = Executors.newSingleThreadScheduledExecutor();

    private void startMethod5() {
        Runnable runnable5 = new Runnable() {
            @Override
            public void run() {
                timeView5.setText("每隔 " + taskcount5++ + " 秒执行");
            }
        };
        scheduledExecutor5.scheduleAtFixedRate(runnable5, 0, 1000, TimeUnit.MILLISECONDS);
    }

6.AlarmManager定时

private void startMethod6() {
        delayStartTask();
    }

    private void delayStartTask() {
        Intent intent = new Intent();
        intent.setAction(DELAY_TASK_ACTION);

        PendingIntent pi = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        AlarmManager am = (AlarmManager) getApplication().getSystemService(Context.ALARM_SERVICE);
        am.set(AlarmManager.RTC, System.currentTimeMillis(), pi);
    }

7.rxJava计时

 

 

 

 

 

 

 

 

你可能感兴趣的:(Android)