“Looper”的版本间的差异
来自个人维基
(以“Looper的作用是在一个线程(thread)中循环取出消息并分发到对应的处理函数中去。 线程通常是没有与之相关联的消息looper的,...”为内容创建页面) |
2015年5月6日 (三) 20:04的最后版本
Looper的作用是在一个线程(thread)中循环取出消息并分发到对应的处理函数中去。
线程通常是没有与之相关联的消息looper的,通过这个类则可以实现这一功能:
1、在目的线程中调用prepare,创建一个looper并关联之
2、调用loop使looper开始工作,开始消息的分发工作
looper与所处理的消息大部分的交互都是通过 Handler这个类来实现的。
典型的用法:
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(); } }
应用程序使用:
new LooperThread().start();
一、prepare函数
/** Initialize the current thread as a looper. * This gives you a chance to create handlers that then reference * this looper, before actually starting the loop. Be sure to call * {@link #loop()} after calling this method, and end it by calling * {@link #quit()}. */ public static void prepare() { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper()); }
sThreadLocal的定义:
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
ThreadLocal是jdk中的一个线程局部变量类,这里表示sThreadLocal是一个线程局部变量,即线程中均保持其独立的副本。
而prepare中作做的则是创建了一个新的Looper并把这个对象赋予了线程局部变量sThreadLocal。
二、loop函数
/** * Run the message queue in this thread. Be sure to call * {@link #quit()} to end the loop. */ public static void loop() { Looper me = myLooper(); if (me == null) { throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); } MessageQueue queue = me.mQueue; Binder.clearCallingIdentity(); final long ident = Binder.clearCallingIdentity(); while (true) { Message msg = queue.next(); // might block if (msg != null) { if (msg.target == null) { // No target is a magic identifier for the quit message. return; } long wallStart = 0; long threadStart = 0; msg.target.dispatchMessage(msg); 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(); } } }
此函数的工作就是不停地从线程局部变量sThreadLocal中不断地取出消息,并分发,我们再来看一下分发函数:
//Handler.java public void dispatchMessage(Message msg) { if (msg.callback != null) { //如果msg自带有callback handleCallback(msg); //调用自带的callback } else { //否则 if (mCallback != null) { //如果handler自带有callback if (mCallback.handleMessage(msg)) { //调用handler自带的callback return; } } handleMessage(msg); //调用关联handler的handleMessage } }