阅读:6191回复:2

Android消息处理机制(Handler和Looper)

楼主#
更多 发布于:2019-03-05 21:41
 一:安卓的消息机制概述    安卓系统真个是依靠消息驱动的,比如按键被按下,网络连接断开,电话打进来等等,系统都是通过不同的消息来通知各个工作模块(线程)来具体实现功能。在源代码设计里面,对于framework层以上的消息机制,主要是设计Looper,Handler,MessageQueue这几个java类,今天我们就一起理一下。
       为了让所有的小白能够明白彻底,我采用先单个文件分析,然后在结合源码看完整的流程。

二:Looper.java
    文件目录:framework/base/core/java/android/os/Looper.java
    在Looper源代码中,重点看一下几个函数:
    ①Looper.prepareMainLooper();
    ②Looper.prepare();
    ③Looper.loop();

Looper.prepare():
public static void prepare() {
        prepare(true);
    }
    private static void prepare(boolean quitAllowed) {
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper(quitAllowed));
    }

该函数调用的时候传入了一个boolean的变量,接下来他判断从sThreadLocal对象中读取不为空,就报异常,再接下来他new了一个Looper对象,并且将这个对象引用保存在名叫sThreadLocal本地静态对象中。

根据代码,总结该方法的作用如下:
1:创建一个Looper对象,传入一个boolean型变量true;
2:一个线程只能创建一个Looper对象,否则报异常;

接下来我们继续看看new Looper()构造方法做了那些事情:
Looper():
   private Looper(boolean quitAllowed) {
        mQueue = new MessageQueue(quitAllowed);
        mThread = Thread.currentThread();
    }

根据代码,总结该方法的作用如下:
1:将boolean型变量quiteAllowed(这里固定传的是true)传入MessageQueue的构造方法,new了一个MessageQueue消息队列对象;
2:Looper对象本地保存了当前线程的引用;

综合起来:Looper.prepare()方法就是创建了一个可以退出的消息队列。

Looper.loop():
public static void loop() {
        final Looper me = myLooper();
        if (me == null) {
            throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
        }
        final MessageQueue queue = me.mQueue;
        ......
        for (;;) {
            Message msg = queue.next(); // might block
            if (msg == null) {
                // No message indicates that the message queue is quitting.
                return;
            }
            ......
            msg.target.dispatchMessage(msg);
            ......
            msg.recycleUnchecked();
        }
    }
public static @Nullable Looper myLooper() {
        return sThreadLocal.get();
    }
我们可以看到首先从刚刚sThreadLocal中取出我们刚刚存进去的Loop对象,然后获取该Looper对象的MessageQueue消息队列对象,然后就是一个死循环,这个或许就是我们的消息循环中的死循环?在循环中调用了queue.next()方法,然后将该消息分发给该消息的target对象处理。我们继续往下追踪源码:

最新喜欢:

zhaoyf13zhaoyf...
If you have nothing to lose, then you can do anything.
沙发#
发布于:2019-03-05 22:24

图片:Android消息机制.png

If you have nothing to lose, then you can do anything.
板凳#
发布于:2019-07-08 19:01
[url]http://190.lsal.cn/195/1329.gif?0728100424873[/url]
游客

返回顶部