参考文章:
深入理解Handler机制

Android 事件机制详解

Android Handler消息机制的理解

android的消息处理机制(图+源码分析)——Looper,Handler,Message

概述

在开发中,Handler通常用于异步消息处理,相关联的类有:

ThreadLocal、Looper、MessageQueue、Message、Handler.

Handler持有MessageQueue和Looper,而Looper持有持有MessageQueue,Message中包含Handler和Runnable成员变量。

其中

  • ThreadLocal是把新创建的Looper对象设置进线程本地存储区里。
  • Looper在后台不断轮询获取Message,后调用msg.target.dispatchMessage()执行,最终会掉用handler的handleMessage()。
  • MessageQueue是一个连表结构的集合。里面装有多个Runnable、Message对象
  • Message类似一个JavaBean,其中包含了消息ID,消息处理对象CallBack以及处理的数据Message.obj等
  • Handler是一个调度器,发送消息会掉用enqueueMessage方法将消息打入MessageQueue,

在一个线程中通过调用Looper.prepare();初始化即可使线程成为Looper线程,通过Looper.loop() 来循环处理消息队列

ThreadLocal

参考资料:解密ThreadLocal
正确理解ThreadLocal

ThreadLocal提供了线程局部变量,在线程的生命周期内起作用,使得各线程能够保持各自独立的一个对象,在Thread中将new出来的对象通过ThreadLocal.set()来设置独立于其他线程的对象,其他线程不可访问,不是用来解决线程同步问题的。

每个线程中都有一个ThreadLocalMap类对象,而ThreadLocal实例就是key,value是真正需要存储的Object,在Android’Handler机制中就是我们的Looper对象。

public final class Looper {    private static final String TAG = "Looper";    // sThreadLocal.get() will return null unless you've called prepare().    static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();    private static Looper sMainLooper;  // guarded by Looper.class    final MessageQueue mQueue;    final Thread mThread;    private Printer mLogging;//....

Looper

通过Looper.prepare();来初始化Looper,并将Looper对象存储到本地线程中,而后创建Handler对象,并掉用Looper.loop()方法进行轮询。

注意:一个线程可以有多个Handler,每个线程中只有一个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对象,并设置进TLS}//.....

Looper.loop()

public static final void loop() {        Looper me = myLooper();  //得到当前线程Looper        MessageQueue queue = me.mQueue;  //得到当前looper的MQ        Binder.clearCallingIdentity();        final long ident = Binder.clearCallingIdentity();        // 开始循环        while (true) {            Message msg = queue.next(); // 取出message            if (msg != null) {                if (msg.target == null) {                    // message没有target为结束信号,退出循环                    return;                }            //...                // 将真正的处理工作交给message的target,即发送消息的handler                msg.target.dispatchMessage(msg);

Handler

首先,来看一下handler 的构造函数,

public Handler(Callback callback, boolean async) {        if (FIND_POTENTIAL_LEAKS) {            final Class<? extends Handler> klass = getClass();            if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&                    (klass.getModifiers() & Modifier.STATIC) == 0) {                Log.w(TAG, "The following Handler class should be static or leaks might occur: " +                    klass.getCanonicalName());            }        }        mLooper = Looper.myLooper();// 设置looper        if (mLooper == null) {            throw new RuntimeException(                "Can't create handler inside thread that has not called Looper.prepare()");        }        mQueue = mLooper.mQueue; //设置MessageQueue        mCallback = callback; //设置CallBack        mAsynchronous = async;    }

Handler对象在构造时,不但会把Looper对象记录在它内部的mLooper成员变量中,还会把Looper对象的消息队列也一并记录

 public Handler(Looper looper, Callback callback, boolean async) {        mLooper = looper;        mQueue = looper.mQueue;        mCallback = callback;        mAsynchronous = async;    }

handler中的post 和send方法都会最终调用sendMessageAtTime方法,通过enqueueMessage方法将消息压入MessageQueue中

 public boolean sendMessageAtTime(Message msg, long uptimeMillis)    {        boolean sent = false;        MessageQueue queue = mQueue;        if (queue != null) {            msg.target = this;  // message的target必须设为该handler!            sent = queue.enqueueMessage(msg, uptimeMillis);        }        else {            RuntimeException e = new RuntimeException(                this + " sendMessageAtTime() called with no mQueue");            Log.w("Looper", e.getMessage(), e);        }        return sent;    }

Handler.dispatchMessage()

这个方法是有Looper.loop()方法调用。

 public void dispatchMessage(Message msg) {        if (msg.callback != null) {            // 如果message设置了callback,即runnable消息,处理callback!            handleCallback(msg);        } else {            // 如果handler本身设置了callback,则执行callback            if (mCallback != null) {                 /* 让activity等来实现Handler.Callback接口,避免了自己编写handler重写handleMessage方法。*/                if (mCallback.handleMessage(msg)) {                    return;                }            }            // 如果message没有callback,则调用handler的钩子方法handleMessage            handleMessage(msg);        }    }    // 处理runnable消息    private final void handleCallback(Message message) {        message.callback.run();  //回调CallBack中的run方法!    }    // new Handler的时候需要实现的方法    public void handleMessage(Message msg) {    }

更多相关文章

  1. Android(安卓)MapView 申请apiKey
  2. android handler
  3. Android的线程使用来更新UI----Thread、Handler、Looper、TimerT
  4. Android主线程里不允许网络操作
  5. android时序图 以及UML中时序图、流程图、状态图、协作图之间的
  6. android中在子线程中更新UI的几种方法
  7. Android(安卓)基础UI编程1
  8. Android(安卓)颜色渲染(十) ComposeShader组合渲染
  9. android的多线程操作(一)

随机推荐

  1. 某一线互联网公司高薪招android高级开发
  2. Framework笔记 | Android(安卓)Framework
  3. 手把手带你打造一个 Android(安卓)热修复
  4. Android(安卓)OOM:内存管理分析和内存泄露
  5. 既然android service是运行在主线程中的,
  6. Json解析(GSON开源库——最简单的json解析
  7. android 应用程序意见反馈
  8. Android筆記
  9. .NET开源了,Visual Studio开始支持 Androi
  10. 报告称Android和iOS设备正慢慢侵蚀PC市场