美文网首页我爱编程
android Handler的原理分析

android Handler的原理分析

作者: 昊昱2018 | 来源:发表于2018-04-15 10:49 被阅读60次

    Handler 是大部分android开发者必须面对且必须熟练掌握的一个线程间通讯的消息句柄。那么Handler

    是如何实现线程间通讯的呢?跟Handler相关的一些类比如:Looper,Message,ThreadLocal 等都是我们必须掌握的。

    第一部分 源码中对Handler,Looper,Message, ThreadLocal的定义:

    (1) Handler 的定义:

     A Handler allows you to send and process  Message and Runnable objects associated with a thread's  MessageQueue.  Each Handler instance is associated with a single thread and that thread's message queue.

    顺便补充一下Handler的两个主要作用:

     1.1 to schedule messages and  runnables to be executed as some point in the future;

    (翻译:在未来某个时间点执行计划好的消息和runable任务)

     1.2 to enqueue an action to be performed on a different thread than your own.

    (翻译:在的另外一个非你所在的线程中执行一个加入队列的动作)

    (2)Looper的定义

    Class used to run a message loop for a thread. Threads by default do not have a message loop associated with them; to create one, call  prepare in the thread that is to run the loop, and then loop to have it process messages until the loop is stopped.

    Looper就不翻译了,直接看原汁原味的定义就行的,翻译水平有限,大伙自己体会。

    (3)Message的定义

    Defines a message containing a description and arbitrary(任意的) data object that can be sent to a  Handler.  This object contains two extra int fields and an extra object field that allow you to not do allocations in many cases.

    (4)ThreadLocal的定义

    所在的包:java.lang.ThreadLocal; 非android专属的

    This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one has its own, independently initialized copy of the variable. ThreadLocal  instances are typically private static fields in classes that wish to associate state with a thread 

    注意点: Each thread holds an implicit reference to its copy of a thread-local variable as long as the thread is alive and the ThreadLocal  instance is accessible; after a thread goes away, all of its copies of  thread-local instances are subject to garbage collection (unless other references to these copies exist).

    第二部分 上述四这之间的关系

    图01

    手绘的,感觉比word绘制起来方便一些;简书没提供绘图工具,有点坑爹哦。

    // sThreadLocal.get() will return null unless you've called prepare(). 

     static final ThreadLocal<Looper>  sThreadLocal = new ThreadLocal<Looper>();

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

     }

    public static @Nullable Looper myLooper() {

            return sThreadLocal.get();

    }

    Looper中的两个方法:prepare() 将当前的Looper赋值给sThreadLocal, 来管理Looper对象 , myLooper() 从sThreadLocal 中读取当前的Looper;

    Looper中的 loop() 方法作用 读取当前线程的Looper, 获取MessageQueen, 对MessageQueen中的

    Message 进行循环遍历,循环中有这样一行代码:

    msg.target.dispatchMessage(msg);

    msg.target是一个Handler对象, 调用dispatchMessage(msg) 来发送消息到对应的Handler中。

    第三部分: Handler中消息分发及处理

        public void dispatchMessage(Message msg) {

         if (msg.callback != null) {

                handleCallback(msg);

            } else {

                if (mCallback != null) {

                    if (mCallback.handleMessage(msg)) {

                        return; }  }

                handleMessage(msg);

            } }

    Handler中dispatchMessage的具体实现, 第一步检查callBack对象能否处理,第二部检查mCallBack

    对象能否处理,第三部调用调用handleMessage() 用户自己实现的处理逻辑来进行处理。

    Handler 中的各种post方法最终调用了enqueueMessage() 方法;

    private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {

            msg.target = this;

            if (mAsynchronous) {

                msg.setAsynchronous(true);

            }

            return queue.enqueueMessage(msg, uptimeMillis);

        }

    MessageQueue的enqueueMessage 的逻辑这里就不详细讨论了,感兴趣的小伙伴可以再看一下源码。

    第四部分: Message的使用注意点

        public static Message obtain() {

            synchronized (sPoolSync) {

                if (sPool != null) {

                    Message m = sPool;

                    sPool = m.next;

                    m.next = null;

                    m.flags = 0; // clear in-use flag

                    sPoolSize--;

                    return m;

                }  }

            return new Message(); }

    Message 使用的时候尽量不要使用new方法, 使用静态的obtain()方法可以节省部分内存开销。

    Handler的原理先分析到这,本文参考资料:

    (1)android开发艺术与探索;

    (2)Handler的源代码;

    (3)Android 异步消息处理机制,https://www.tuicool.com/articles/ymuyMfY

    相关文章

      网友评论

        本文标题:android Handler的原理分析

        本文链接:https://www.haomeiwen.com/subject/keqdkftx.html