博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Looper源码
阅读量:7092 次
发布时间:2019-06-28

本文共 3842 字,大约阅读时间需要 12 分钟。

在Android-27中查看源码

在看Handler源码时会发现MessageQueue来自于Looper,下面来看Looper的源码:

private Looper(boolean quitAllowed) {        mQueue = new MessageQueue(quitAllowed);        mThread = Thread.currentThread();    }

在构造函数中创建了MessageQueue并且将当前线程和Looper关联起来。但该方法是私有的,无法直接new对象。那么如何创建对象呢?在Handler的构造函数中默认的Looper是通过Looper.myLooper()获得的,我们来看看这个方法。

public static @Nullable Looper myLooper() {        return sThreadLocal.get();    }

该方法返回和当前线程相关联的Looper,如果当前线程没有关联的Looper则返回null。

如何将Looper与线程关联呢?我们在下面的方法中找到了答案。

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));    }

在Looper.prepare()方法中创建了Looper对象并保存在ThreadLocal中,在使用时通过Looper.myLooper()将保存的Looper取出来。关于ThreadLocal可以参考文章

接下来,我们看到了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;        // Make sure the identity of this thread is that of the local process,        // and keep track of what that identity token actually is.        Binder.clearCallingIdentity();        final long ident = Binder.clearCallingIdentity();        for (;;) {            Message msg = queue.next(); // might block            if (msg == null) {                // No message indicates that the message queue is quitting.                return;            }            // This must be in a local variable, in case a UI event sets the logger            final Printer logging = me.mLogging;            if (logging != null) {                logging.println(">>>>> Dispatching to " + msg.target + " " +                        msg.callback + ": " + msg.what);            }            final long slowDispatchThresholdMs = me.mSlowDispatchThresholdMs;            final long traceTag = me.mTraceTag;            if (traceTag != 0 && Trace.isTagEnabled(traceTag)) {                Trace.traceBegin(traceTag, msg.target.getTraceName(msg));            }            final long start = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis();            final long end;            try {                msg.target.dispatchMessage(msg);                end = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis();            } finally {                if (traceTag != 0) {                    Trace.traceEnd(traceTag);                }            }            if (slowDispatchThresholdMs > 0) {                final long time = end - start;                if (time > slowDispatchThresholdMs) {                    Slog.w(TAG, "Dispatch took " + time + "ms on "                            + Thread.currentThread().getName() + ", h=" +                            msg.target + " cb=" + msg.callback + " msg=" + msg.what);                }            }            if (logging != null) {                logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);            }            // Make sure that during the course of dispatching the            // identity of the thread wasn't corrupted.            final long newIdent = Binder.clearCallingIdentity();            if (ident != newIdent) {                Log.wtf(TAG, "Thread identity changed from 0x"                        + Long.toHexString(ident) + " to 0x"                        + Long.toHexString(newIdent) + " while dispatching to "                        + msg.target.getClass().getName() + " "                        + msg.callback + " what=" + msg.what);            }            msg.recycleUnchecked();        }    }

在loop方法中存在一个无限循环,不断从消息队列中取出消息,然后交给msg.target(即Handler)去调用dispatchMessage处理取出的消息。只有在消息队列为空的时候才跳出循环。

转载地址:http://wtiql.baihongyu.com/

你可能感兴趣的文章
spm中头动绘图的理解,自带数据集
查看>>
车辆管理系统之继续自己的任务(五)
查看>>
谁该赋予一款产品灵魂?
查看>>
自我总结(八)- 新学期
查看>>
I.MX6 wm8962 0-001a: DC servo timed out
查看>>
ACM进阶计划
查看>>
Spring3 表达式语言(SpEL)介绍
查看>>
【Java学习笔记之七】java函数的语法规则总结
查看>>
5.23. msgpack
查看>>
【Java学习笔记之三十三】详解Java中try,catch,finally的用法及分析
查看>>
IE6 png图片实现半透明的方法
查看>>
程序猿的日常——Java基础之clone、序列化、字符串、数组
查看>>
Gulp Error: Cannot find module &#39;jshint/src/cli&#39;
查看>>
又见尾递归
查看>>
Ruby中如何识别13位的时间戳
查看>>
Linux 命令详解(二)awk 命令
查看>>
RobotFramework自动化4-批量操作案例
查看>>
Android 缓存目录 Context.getExternalFilesDir()和Context.getExternalCacheDir()方法
查看>>
MVC4 WebAPI(二)——Web API工作方式
查看>>
JAVA学习Swing章节标签JLabel中图标的使用
查看>>