Android studio Handler消息处理2

两种方法的区别

那么,为什么 Android 系统会提供两种方法来发送消息任务呢?这当然和使用场景相关了,根据不同的使用场景,这两种方法还是有区别的。当然,在平常的使用过程中或许你不会考虑这么多,因为在具体的使用场景中,你很可能“不经意”地就将两种方法的使用场景给区别开了:

  • 当发送者知道如何处理消息的话,使用 Handler.post() 方法。发送者直接在 run() 方法中处理任务。

  • 当接收者知道如何处理消息的话,使用 Handler.sendMessage() 方法。发送者将 Message 对象发射出去后,handler (接收者)调用 handleMessage() 方法处理任务。

实例:倒计时

下面,我们用 Handler 来实现倒计时功能。先来分析一下倒计时的相关功能需求:

  • 需要知道总时间和每一步的间隔时间。

  • 每次到了间隔时间就回调通知,总时间结束后也要回调通知。

根据这个需求,我们可以大致猜想一下如何实现:

  • 需要提供两个构造参数的构造方法,一个是总时间,一个是间隔时间。

  • 需要提供两个抽象方法供子类实现,一个是每次到了间隔时间的回调通知,另一个是总时间结束后的回调通知。

有了这个思路,实现就很简单了,下面直接给出代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
public abstract class Timer {

    private long mMillisInFuture;
    private long mCountdownInterval;
    private long mStopTimeInFuture;
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            // 计算剩余时间
            long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();
            if (millisLeft <= 0) {
                // 如果剩余时间小于或等于 0, 则回调 onFinish() 方法。
                onFinish();
            } else if (millisLeft < mCountdownInterval) {
                // 当剩余时间小于一次间隔时间时,不回调 onTick() 方法,直接等到最后再发送
                sendMessageDelayed(obtainMessage(), millisLeft);
            } else {
                // 回调 onTick() 方法,并在一次间隔时间后再次发送消息。
                onTick(millisLeft);
                sendMessageDelayed(obtainMessage(), mCountdownInterval);
            }
        }
    };

    public Timer(long millisInFuture, long countdownInterval) {
        mMillisInFuture = millisInFuture;
        mCountdownInterval = countdownInterval;
    }

    /**
     * 调用 start() 方法以启动倒计时
     * @return
     */
    public Timer start() {
        if (mMillisInFuture < 0) {
            onFinish();
            return this;
        }
        // 获取倒计时完成的系统时间
        mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture;
        // 发送第一个消息
        mHandler.sendMessage(mHandler.obtainMessage());
        return this;
    }

    /**
     * 每经过一次间隔时间就回调一次 onTick 方法
     * @param millionLeft   剩余时间
     */
    abstract void onTick(long millionLeft);

    /**
     * 倒计时完成后,回调 onFinish() 方法
     */
    abstract void onFinish();
}

其实上面的代码是 Android 系统中 CountDownTimer 类的简化版,CountDownTimer 增加了线程安全机制并处理了一些特殊情况,有兴趣的朋友可以自行查阅。


文章转载自:Handler与异步消息处理_慕课手记 (imooc.com)

原文地址:https://www.cnblogs.com/1329197745a/p/14905699.html