转载请注明出处:http://blog.csdn.net/zhouli_csdn/article/details/45668285


安卓消息处理类:

Looper、Handler、MessageQueue、Message、ThreadLocal、ThreadLocal.Values、HandlerThread。

Looper:

线程默认是没有消息循环的,要为一个线程创建一个消息循环通过调用prepare(),然后在调用loop()方法进入消息循环(这意味着线程将一直在此方法循环)。例如:
class LooperThread extends Thread {      public Handler mHandler;      public void run() {          Looper.prepare();          mHandler = new Handler() {              public void handleMessage(Message msg) {                  // process incoming messages here              }          };          Looper.loop();      }  }
那么到这里你肯定会想安卓的主线程并没有prepare和loop也可以创建Handler,处理消息循环。这是因为安卓在创建主线程的时候已经为我们添加了消息循环。
那么Looper如何管理每一个线程对应的一个looper的呢?
public final class 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;    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));    }    public static void prepareMainLooper() {        prepare(false);        synchronized (Looper.class) {            if (sMainLooper != null) {                throw new IllegalStateException("The main Looper has already been prepared.");            }            sMainLooper = myLooper();        }    }    public static Looper getMainLooper() {        synchronized (Looper.class) {            return sMainLooper;        }    }    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;        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            Printer logging = me.mLogging;            if (logging != null) {                logging.println(">>>>> Dispatching to " + msg.target + " " +                        msg.callback + ": " + msg.what);            }            msg.target.dispatchMessage(msg);            if (logging != null) {                logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);            }            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.recycle();        }    }    public static Looper myLooper() {        return sThreadLocal.get();    }
下面通过图解讲解上面的过程:(prepare调用threadLocal的get的set方法)

Handler类

构造函数: 1)Handler handler = new Handler(),内部会调用public Handler(Callback callback, boolean async)方法, 将Handler的成员变量mLooper和mQueue赋值为当前线程的looper对象和对应的消息队列,如果当前线程没有looper会抛出异常。 2)Handler handle = new Handler(Looper looper),内部会调用public Handler(Looper looper, Callback callback, boolean async),将参数的looper对象传递给handler的mHandler对象,mQueue对象赋值。通过此方法可以在其它线程中为主线程创建Handler,例如:new Handler(Looper.getMainLooper());
handler的sendMessage()方法,在内部会将handler对象赋值为Message的mTarget中,然后调用mQueue将消息发送到线程的消息队列中。

Message类

Message类内部会保存一个Handler对象mTarget。
Looper的loop方法,取出消息,然后调用Message对象中的handler的dispatchMessage方法,dispatchMessage根据callback是否为空执行handleMessage方法。
流程图如下:
HandlerThread是一个可以简单创建一个进行消息处理的线程类。

总结

1)Thread最多与一个looper建立联系。 2)一个looper有且仅有一个MessageQueue 3)一个handler只能与一个looper关联 4)一个Message只能与一个handler关联 这四个一对一的关系使得消息发送和处理得到正确的相应。











更多相关文章

  1. [安卓开发Android][叠层 层叠 卡片效果]RecyclerView与CardView
  2. Android(安卓)RecyclerView 滑动到指定item(position)并加动画
  3. Android快速开发框架dyh详解(五)---基础层的使用
  4. tab使用 TabActivity TabHost Tabspec常用方法
  5. Android下VideoView的研究
  6. Android--H5交互简介
  7. Android(安卓)Dialog 生命周期
  8. Android框架保证View更新必须在主线程的解读
  9. android JNI 多线程 C函数回调

随机推荐

  1. 从Android 1.0到Android 8.0,盘点每一代系
  2. 微软和Wistron再度联手,Android和Chrome O
  3. Android进阶(一)View体系
  4. (一)Android应用程序及组件简介
  5. 【Android实战开发】3G技术和Android发展
  6. AndroidManifest.xml 详解 (四) 之uses-p
  7. 阿里ctf-2014 android 第三题——so动态
  8. 成品app直播源码,Android自屏幕底部滑出更
  9. Android中Handler异步线程
  10. 3. Android(安卓)MultiMedia框架完全解析