android 中Chronometer类源码分析

1, 概述

Chronometer在平时开发时使用广泛,使用简单, 只需要调用三个简单的方法就可以。

2, Chronometer

Chronometer是TextView的子类,这个组只能以1秒的时间间隔进行计时,并显示出计时结果。使用Handler来实现。

2.1 开发方法

Chronometer开发很简单,

private  Chronometer timer;
timer = (Chronometer)findViewById(R.id.timer);  // 定义并获取组件
timer.setBase(SystemClock.elapsedRealtime()); // 设置起始时间
timer.start(); // 开始每隔1s开始计时

timer.stop(); // 停止计时

2.2 原理分析

1, setBase

setBase方法如下,

public void setBase(long base) {
        mBase = base;  // 设置时间基准
        dispatchChronometerTick(); // 回调
        updateText(SystemClock.elapsedRealtime()); // 跟新显示
    }

setBase方法主要是设置mBase变量,该变量是时间基准。

2, start方法

public void start() {
        mStarted = true;
        updateRunning();
    }

mStarted变量是记录计时是否开始。

updateRunning方法如下,

private void updateRunning() {
        boolean running = mVisible && mStarted; // 如果未开始计时,并且该控件可见
        if (running != mRunning) {
            if (running) {
                updateText(SystemClock.elapsedRealtime()); // 获取当前时间然后更新
                dispatchChronometerTick(); // 回调
                mHandler.sendMessageDelayed(Message.obtain(mHandler, TICK_WHAT), 1000);
            } else {
                mHandler.removeMessages(TICK_WHAT);// 移除消息。
            }
            mRunning = running;
        }
    }

mVisible变量表示该控件是否可见, mRunning变量表示是否在计时。

利用handler进行计时,相当于一个死循环,每隔1s钟执行一次更新和回调。一直到调用stop方法为止。

private Handler mHandler = new Handler() {
        public void handleMessage(Message m) {
            if (mRunning) {
                updateText(SystemClock.elapsedRealtime());
                dispatchChronometerTick();
                sendMessageDelayed(Message.obtain(this, TICK_WHAT), 1000);
            }
        }
    };

3,stop

public void stop() {
        mStarted = false;
        updateRunning();
    }

将mStarted赋值为空,然后在updateRunning方法中移除消息,这样就终止了计时。

mHandler.removeMessages(TICK_WHAT);// 移除消息。

4, updateText

private synchronized void updateText(long now) {
        mNow = now;
        long seconds = now - mBase;
        seconds /= 1000;
        String text = DateUtils.formatElapsedTime(mRecycle, seconds);

        if (mFormat != null) {
            Locale loc = Locale.getDefault();
            if (mFormatter == null || !loc.equals(mFormatterLocale)) {
                mFormatterLocale = loc;
                mFormatter = new Formatter(mFormatBuilder, loc);
            }
            mFormatBuilder.setLength(0);
            mFormatterArgs[0] = text;
            try {
                mFormatter.format(mFormat, mFormatterArgs);
                text = mFormatBuilder.toString();
            } catch (IllegalFormatException ex) {
                if (!mLogged) {
                    Log.w(TAG, "Illegal format string: " + mFormat);
                    mLogged = true;
                }
            }
        }
        setText(text);
    }

首先将当前时间减去基准时间(ms),然后转化为s,转化为特定的时间格式,最后调用setText方法显示到界面。

5, dispatchChronometerTick

void dispatchChronometerTick() {
        if (mOnChronometerTickListener != null) {
            mOnChronometerTickListener.onChronometerTick(this);
        }
    }

mOnChronometerTickListener是OnChronometerTickListener对象,而OnChronometerTickListener是Chronometer的内部接口,

public interface OnChronometerTickListener {
        void onChronometerTick(Chronometer chronometer);
    }

mOnChronometerTickListener变量是通过setOnChronometerTickListener进行赋值的。

public void setOnChronometerTickListener(OnChronometerTickListener listener) {
        mOnChronometerTickListener = listener;
    }

由此看来,这是一个标准的接口回调方法。

 

如果需要回调,只需要继承OnChronometerTickListener接口,然后调用setOnChronometerTickListener方法,最后实现onChronometerTick方法就可以了。

onChronometerTick方法会在调用start时回调一次,然后每个1s回调一次,一直到调用stop方法为止。

 

小结:

1,Chronometer使用简单,但是只能间隔1s进行计时。

2,有标准的回调方法,并且回调方法也是间隔1s执行一次。

3,使用handler实现,其实开发时也可以利用handler简单的写一个类,这样可以控制间隔时间。

    原文作者:Android源码分析
    原文地址: https://blog.csdn.net/u012439416/article/details/70186078
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞