而对于Hanlder的原理和消息处理机制并不清楚。找了两篇比较深入的博客:
http://www.cnblogs.com/angeldevil/p/3340644.html AngelDevil的博客
http://blog.csdn.net/amazing7/article/details/51424038 amazing7的博客
学习了一下,又对照了源码,小有收获,俗话说“好记性不如烂笔头”,所以做一下笔记,总结一下,方便以后回顾。
AngelDevil的博客的博客中指出Android是消息驱动的,这一点,看一下类ActivityThread就一目了然了。
public final class ActivityThread {
//……
final ApplicationThread mAppThread = new ApplicationThread();
//……
final H mH = new H();
//……
final Handler getHandler() {
return mH;
}
//……
private class ApplicationThread extends ApplicationThreadNative {//……}
//……
private class H extends Handler {//……}
//……
public static void main(String[] args) {
//……
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
// End of event ActivityThreadMain.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
}
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
final ApplicationThread mAppThread = new ApplicationThread();
final H mH = new H();
final Handler getHandler() {
return mH;
}
private class ApplicationThread extends ApplicationThreadNative {//……}
private class H extends Handler {//……}
getHanlder就是H,H继承于Handler,而H(extends Handler)的handleMessage(){}中接受的都是一些系统消息。
也就是说,在主线程中,有一个Looper轮询器,在Looper.prepareMainLooper()和Looper.loop()之间创建了ActivityThread实例,并获得了ActivityThread内部的Handler实例,相当于在Looper的两个方法中间创建了Hanlder。Android正是通过这个Handler进行的消息传递。
下面看一下Android源码中提供的Looper典型使用
/**
* ……
* This is a typical example of the implementation of a Looper thread,
* using the separation of {@link #prepare} and {@link #loop} to create an
* initial Handler to communicate with the Looper.
*//这是一个Looper线程实现的典型案例,使用Looper.prepare()和Looper.loop()中间被隔开的部分创建
*//和初始化Handler,以便与Looper进行通信。
*
* 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();
* }
* }
*/public final class Looper {//……}
/**
* 这个类用于为一个线程运行一个消息循环。默认的线程并没有一个消息循环与它们相关联;
* 在线程中调用此类的prepare()方法来创建一个消息循环并且运行这个循环,然后调用Loop()
* 来使消息循环处理消息直到这个循环被终止。
*
* 大多数与消息循环的交互是通过Handler类来实现的。
*
* 这是一个Looper线程实现的典型案例,通过使用Looper.prepare()和Looper.loop()中间被隔开的部分创建
* 和初始化Handler,以便与Looper进行通信。
* This is a typical example of the implementation of a Looper thread,
* using the separation of {@link #prepare} and {@link #loop} to create an
* initial Handler to communicate with the Looper.
*
*
* 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();
* }
* }
*/
public final class Looper {
private static final String TAG = "Looper";
// sThreadLocal.get() 将返回null,除非你已经调用了prepare().
static final ThreadLocal sThreadLocal = new ThreadLocal();
private static Looper sMainLooper; // guarded by Looper.class
final MessageQueue mQueue;
final Thread mThread;
private Printer mLogging;
/** 将当前线程初始化为一个轮询器(looper)。(也就是在当前线程中维持一个轮询器)
* 这样你就可以创建handler,handler之后会在开始轮询之前引用这个轮询器。要确保在调用
* 这个方法后调用{@link #loop()}方法,并且调用{@link #quit()}方法结束它。
*/
public static void prepare() {
prepare(true);
}
/**
* 这个方法中创建了Looper对象,并与线程关联
*
*/
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), 并标记为一个应用的主轮询器。
* 应用的朱轮询器由Android环境创建(在ActivityThread#main()中被调用),
* 所以你不需要自己调用这个方法。可以看:{@link #prepare()}。
*/
public static void prepareMainLooper() {
prepare(false);
synchronized (Looper.class) {
if (sMainLooper != null) {
throw new IllegalStateException("The main Looper has already been prepared.");
}
sMainLooper = myLooper();
}
}
/**
* 返回应用的主轮询器(looper),它存在于应用的主线程。
*/
public static Looper getMainLooper() {
synchronized (Looper.class) {
return sMainLooper;
}
}
/**
* 在当前线程中运行(轮询)消息队列。确保调用{@link #quit()}方法结束循环。
*/
public static void loop() {
//获取当前线程的Looper
final Looper me = myLooper();
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
//获取Looper中的消息队列
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
Printer logging = me.mLogging;
if (logging != null) {
logging.println(">>>>> Dispatching to " + msg.target + " " +
msg.callback + ": " + msg.what);
}
//###通过message的target(Handler)分发处理消息
msg.target.dispatchMessage(msg);
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();
}
}
/**
* 返回与当前线程关联的Looper对象,如果当前线程未关联Looper,返回null。
*/
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
/**
* 返回与当前线程关联的 {@link MessageQueue} 对象。这个方法必须在运行着Looper的线程中
* 调用,否则会抛出空指针异常。
*/
public static @NonNull MessageQueue myQueue() {
return myLooper().mQueue;
}
/**
* 私有构造方法。
* 其中创建了消息队列(MessageQueue)。获取了当前线程。
* 在prepare()方法中调用创建实例。可以通过myLooper()方法获取looper实例。
*/
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
/**
* 停止当前轮询器。
*
* 使{@link #loop} 停止,不再处理消息队列中的任何消息。
*
* 轮询器停止(轮询)后,任何尝试发送消息到队列都将失败。
* 例如,{@link Handler#sendMessage(Message)} 方法将会返回false。
*
* 使用这个方法可能不安全,因为一些消息可能在轮询器结束之前没有被分发处理。
* 考虑使用{@link #quitSafely} 代替,以确保所有待完成的工作能被井井有条地完成。
*
*/
public void quit() {
mQueue.quit(false);
}
/**
* 安全停止当前轮询器。
*
* 一旦消息队列中所有余下的到期的消息被分发处理,就使循环{@link #loop} 停止。
* 然而,还有一定时间到期的延迟消息不会在循环终止之前分发处理。
*
* 轮询器停止(轮询)后,任何尝试发送消息到队列都将失败。
* 例如,{@link Handler#sendMessage(Message)} 方法将会返回false。
*
*/
public void quitSafely() {
mQueue.quit(true);
}
/**
* 获得与这个轮询器关联的线程。
*
* @return 轮询器的线程
*/
public @NonNull Thread getThread() {
return mThread;
}
/**
* 获得轮询器的消息队列。
*
* @return 轮询器的消息队列
*/
public @NonNull MessageQueue getQueue() {
return mQueue;
}
//......
}
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null)
return (T)e.value;
}
return setInitialValue();
}
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
//获取线程t的ThreadLocalMap
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
//为线程t的(ThreadLocalMap)threadLocals赋值
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
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();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
public Handler(Looper looper, Callback callback, boolean async) {
mLooper = looper;
mQueue = looper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
public final boolean sendMessage(Message msg)
{
return sendMessageDelayed(msg, 0);
}
public final boolean sendEmptyMessage(int what)
{
return sendEmptyMessageDelayed(what, 0);
}
public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
Message msg = Message.obtain();
msg.what = what;
return sendMessageDelayed(msg, delayMillis);
}
public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) {
Message msg = Message.obtain();
msg.what = what;
return sendMessageAtTime(msg, uptimeMillis);
}
public final boolean sendMessageDelayed(Message msg, long delayMillis)
{
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
MessageQueue queue = mQueue;
if (queue == null) {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
return false;
}
return enqueueMessage(queue, msg, uptimeMillis);
}
public final boolean post(Runnable r){
return sendMessageDelayed(getPostMessage(r), 0);
}
public final boolean postAtTime(Runnable r, long uptimeMillis){
return sendMessageAtTime(getPostMessage(r), uptimeMillis);
}
public final boolean postAtTime(Runnable r, Object token, long uptimeMillis){
return sendMessageAtTime(getPostMessage(r, token), uptimeMillis);
}
public final boolean postDelayed(Runnable r, long delayMillis){
return sendMessageDelayed(getPostMessage(r), delayMillis);
}
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}
private static Message getPostMessage(Runnable r, Object token) {
Message m = Message.obtain();
m.obj = token;
m.callback = r;
return m;
}
private static void handleCallback(Message message) {
message.callback.run();
}
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
public final class Message implements Parcelable {
public int what;
public int arg1;
public int arg2;
public Object obj;
//......
/*package*/ Handler target;
/*package*/ Runnable callback;
// sometimes we store linked lists of these things
/*package*/ Message next;
private static final Object sPoolSync = new Object();
private static Message sPool;
private static int sPoolSize = 0;
private static final int MAX_POOL_SIZE = 50;
private static boolean gCheckRecycle = true;
/**
* Return a new Message instance from the global pool. Allows us to
* avoid allocating new objects in many cases.从全局池中返回一个新的消息实例。
* 使我们在很多情况下避免分配新的对象。
*/
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();
}
//......
/**
* Return a Message instance to the global pool.回收一个消息放到全局池。
*
* You MUST NOT touch the Message after calling this function because it has
* effectively been freed. It is an error to recycle a message that is currently
* enqueued or that is in the process of being delivered to a Handler.
* 调用这个方法后你就不能再用Message,因为它已经被有效释放。回收一个正在列队或正在被
* 分配给Hanlder的过程中的Message是错误的。
*
*/
public void recycle() {
if (isInUse()) {
if (gCheckRecycle) {
throw new IllegalStateException("This message cannot be recycled because it "
+ "is still in use.");
}
return;
}
recycleUnchecked();
}
/**
* Recycles a Message that may be in-use.
* Used internally by the MessageQueue and Looper when disposing of queued Messages.
*/
void recycleUnchecked() {
// Mark the message as in use while it remains in the recycled object pool.
// Clear out all other details.
flags = FLAG_IN_USE;
what = 0;
arg1 = 0;
arg2 = 0;
obj = null;
replyTo = null;
sendingUid = -1;
when = 0;
target = null;
callback = null;
data = null;
synchronized (sPoolSync) {
if (sPoolSize < MAX_POOL_SIZE) {
next = sPool;
sPool = this;
sPoolSize++;
}
}
}
//......
public void setTarget(Handler target) {
this.target = target;
}
public Handler getTarget() {
return target;
}
//......
/**
* Sends this Message to the Handler specified by {@link #getTarget}.
* Throws a null pointer exception if this field has not been set.
*/
public void sendToTarget() {
target.sendMessage(this);
}
/** Constructor (but the preferred way to get a Message is to call {@link #obtain() Message.obtain()}).
* 构造器 (但是获得一个Message的首选方式是调用Message.obtain())
*/
public Message() {
}
//......
}
public static void loop() {
final Looper me = myLooper();//获得当前线程的Looper
if (me == null) {//如果为null,抛出运行时异常("没有Looper;线程中没有调用Looper.prepare()
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."
}
final MessageQueue queue = me.mQueue; //从Looper中获得消息队列
// ……
//开始无限循环
for (;;) {
//不断从消息队列中取出消息(Message)
Message msg = queue.next(); // might block 可能阻断
if (msg == null) {
// No message indicates that the message queue is quitting. 如果没有消息标识(没有
return;
}
//……
try { //msg.target其实是一个Hanlder,Hanlder发送消息时,会把当前这个handler作为target
msg.target.dispatchMessage(msg);//Hanlder分发消息
} finally {
//……
}
//……
msg.recycleUnchecked();
}
}
/**
* Callback interface you can use when instantiating a Handler to avoid
* having to implement your own subclass of Handler.
* 实例化一个handler时,为避免必须实现你自己的Hanlder的子类,你可以使用回调接口。
*/
public interface Callback {
public boolean handleMessage(Message msg);
}
/**
* Subclasses must implement this to receive messages.//子类必须实现这个方法来接收消息。
*/
public void handleMessage(Message msg) {
}
/**
* Handle system messages here.这里处理系统的消息。
*/
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
private static void handleCallback(Message message) {
message.callback.run();
}
1. 一个线程中要想创建Handler发送处理消息,要先调用Looper.prepare()和Looper.loop()来创建一个消息队列(MessageQueue)开启一个轮询器与线程关联。
2. 在Looper的两个方法中间创建Handler,handler创建时要拿到与当前线程关联的轮询器(Looper)和轮询器管理的消息队列(MessageQueue)
3. Handler发送消息(Message)其实是发送到了2中的消息队列(MessageQueue),发送消息同时,Handler将自己设置给Message的target
4. 消息是在Looper的loop()方法中循环取出处理,最终由Message的target也就是发送自己的handler处理。
Handler:
创建:在Looper.prepare()和Looper.loop()之间创建
作用:发送消息(Message)到所在线程关联的轮询器(Looper)的消息队列(MessageQueue),并将自己作为target设置给Message
处理消息,由dispatchMessage()分发给①Callback的handleMessage()、②Handler的handleMessage()或③Handler的handleCallback()处理
Looper 轮询器
创建:由自己的prepare()方法创建并关联当前线程。
作用:Looper.perpare(),创建自己的实例同时创建一个MessageQueue,并将自己设置给当前线程
Looper.loop()从当前线程拿到Looper及其MessageQueue,循环遍历MessageQueue,取出消息,交给Message的target(发送消息的handler)处理
*Looper.myLooper():获得当前线程所关联的Looper。
MessageQueue 消息队列
创建:Looper的构造方法中创建,最终由Looper的prepare()方法创建
作用:接收handler发送消息时加入进来的消息,将其放入队列中,先入先出
Message 消息
创建:优先用Message.obtain()获取实例,Handler发送消息时创建,最终由MessageQueue管理
作用:携带消息内容传递数据,或作为一个信号(what)
注意:Message在被发送时会将发送它的Handler作为target,在使用Handler的post系列方法时,传入的Runnable对象由Message的callback得到。