标签:
handler 主要用于发送消息和接收消息,handler可以更新ui延时更新ui
looper 主要用于从消息队列中循环读取消息并把消息发送给handler
messageQueue 是一个消息队列,用来存储消息。
下面从源码的角度分析三者的关系:
Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); } }; handler.sendEmptyMessage(1);
public Handler() { this(null, false); }
1 public Handler(Callback callback, boolean async) { 2 if (FIND_POTENTIAL_LEAKS) { 3 final Class<? extends Handler> klass = getClass(); 4 if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) && 5 (klass.getModifiers() & Modifier.STATIC) == 0) { 6 Log.w(TAG, "The following Handler class should be static or leaks might occur: " + 7 klass.getCanonicalName()); 8 } 9 } 10 11 mLooper = Looper.myLooper(); 12 if (mLooper == null) { 13 throw new RuntimeException( 14 "Can‘t create handler inside thread that has not called Looper.prepare()"); 15 } 16 mQueue = mLooper.mQueue; 17 mCallback = callback; 18 mAsynchronous = async; 19 }
看到11行 就可以看到handler联系在一块了获取一个looper对象
1 public static Looper myLooper() { 2 return sThreadLocal.get(); 3 }
下面看一下
handler.sendEmptyMessage(1);
里面做了什么东东!
经过一路跟踪来到了
1 public boolean sendMessageAtTime(Message msg, long uptimeMillis) { 2 MessageQueue queue = mQueue; 3 if (queue == null) { 4 RuntimeException e = new RuntimeException( 5 this + " sendMessageAtTime() called with no mQueue"); 6 Log.w("Looper", e.getMessage(), e); 7 return false; 8 } 9 return enqueueMessage(queue, msg, uptimeMillis); 10 }
下面看看
enqueueMessage(queue, msg, uptimeMillis) 做了什么
1 private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) { 2 msg.target = this; 3 if (mAsynchronous) { 4 msg.setAsynchronous(true); 5 } 6 return queue.enqueueMessage(msg, uptimeMillis); 7 }
看到第2行 其实就知道了 message跟handler关联起来了 msg.target 就是当前的handler实例。
现在我们来看一下MessageQueue类中enqueueMessage()这个方法做了什么!其实想一下也知道肯定是往消息队列尾部添加一个消息
下面我们看看该方法
1 final boolean enqueueMessage(Message msg, long when) { 2 if (msg.isInUse()) { 3 throw new AndroidRuntimeException(msg + " This message is already in use."); 4 } 5 if (msg.target == null) { 6 throw new AndroidRuntimeException("Message must have a target."); 7 } 8 9 boolean needWake; 10 synchronized (this) { 11 if (mQuiting) { 12 RuntimeException e = new RuntimeException( 13 msg.target + " sending message to a Handler on a dead thread"); 14 Log.w("MessageQueue", e.getMessage(), e); 15 return false; 16 } 17 18 msg.when = when; 19 Message p = mMessages; 20 if (p == null || when == 0 || when < p.when) { 21 // New head, wake up the event queue if blocked. 22 msg.next = p; 23 mMessages = msg; 24 needWake = mBlocked; 25 } else { 26 // Inserted within the middle of the queue. Usually we don‘t have to wake 27 // up the event queue unless there is a barrier at the head of the queue 28 // and the message is the earliest asynchronous message in the queue. 29 needWake = mBlocked && p.target == null && msg.isAsynchronous(); 30 Message prev; 31 for (;;) { 32 prev = p; 33 p = p.next; 34 if (p == null || when < p.when) { 35 break; 36 } 37 if (needWake && p.isAsynchronous()) { 38 needWake = false; 39 } 40 } 41 msg.next = p; // invariant: p == prev.next 42 prev.next = msg; 43 } 44 } 45 if (needWake) { 46 nativeWake(mPtr); 47 } 48 return true; 49 }
我们很清楚的看到了 22和41行把这个消息next 就把这个消息添加到了消息队列中,我们把
handler.sendEmptyMessage(1);分析完了
那么发送过消息后怎么又回调到 Handler的handleMessage方法中呢!
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
下面不得不说说looper了
看一下looper两个重要的方法
1 public static void prepare() { 2 prepare(true); 3 } 4 5 private static void prepare(boolean quitAllowed) { 6 if (sThreadLocal.get() != null) { 7 throw new RuntimeException("Only one Looper may be created per thread"); 8 } 9 sThreadLocal.set(new Looper(quitAllowed)); 10 } 11 12 private Looper(boolean quitAllowed) { 13 mQueue = new MessageQueue(quitAllowed); 14 mRun = true; 15 mThread = Thread.currentThread(); 16 }
执行prepare 方法就是新建一个looper对象和MessageQueue对象
再看一下looper 的另外一个重要的方法
1 public static void loop() { 2 final Looper me = myLooper(); 3 if (me == null) { 4 throw new RuntimeException("No Looper; Looper.prepare() wasn‘t called on this thread."); 5 } 6 final MessageQueue queue = me.mQueue; 7 8 // Make sure the identity of this thread is that of the local process, 9 // and keep track of what that identity token actually is. 10 Binder.clearCallingIdentity(); 11 final long ident = Binder.clearCallingIdentity(); 12 13 for (;;) { 14 Message msg = queue.next(); // might block 15 if (msg == null) { 16 // No message indicates that the message queue is quitting. 17 return; 18 } 19 20 // This must be in a local variable, in case a UI event sets the logger 21 Printer logging = me.mLogging; 22 if (logging != null) { 23 logging.println(">>>>> Dispatching to " + msg.target + " " + 24 msg.callback + ": " + msg.what); 25 } 26 27 msg.target.dispatchMessage(msg); 28 29 if (logging != null) { 30 logging.println("<<<<< Finished to " + msg.target + " " + msg.callback); 31 } 32 33 // Make sure that during the course of dispatching the 34 // identity of the thread wasn‘t corrupted. 35 final long newIdent = Binder.clearCallingIdentity(); 36 if (ident != newIdent) { 37 Log.wtf(TAG, "Thread identity changed from 0x" 38 + Long.toHexString(ident) + " to 0x" 39 + Long.toHexString(newIdent) + " while dispatching to " 40 + msg.target.getClass().getName() + " " 41 + msg.callback + " what=" + msg.what); 42 } 43 44 msg.recycle(); 45 } 46 }
我们看到这个是“死循环”,看27行
msg.target.dispatchMessage(msg);
其实就是调用的handler 的
dispatchMessage()方法,看一下这个方法
1 /** 2 * Handle system messages here. 3 */ 4 public void dispatchMessage(Message msg) { 5 if (msg.callback != null) { 6 handleCallback(msg); 7 } else { 8 if (mCallback != null) { 9 if (mCallback.handleMessage(msg)) { 10 return; 11 } 12 } 13 handleMessage(msg); 14 } 15 }
呵呵终于看到 handleMessage方法回调了。大功告成。
看到别人的博看上面讲 looper的prepare和loop()方法在activity初始化时就执行了,以前死活找不到在哪执行了
今天终于找到了
1 public static void main(String[] args) { 2 SamplingProfilerIntegration.start(); 3 4 // CloseGuard defaults to true and can be quite spammy. We 5 // disable it here, but selectively enable it later (via 6 // StrictMode) on debug builds, but using DropBox, not logs. 7 CloseGuard.setEnabled(false); 8 9 Environment.initForCurrentUser(); 10 11 // Set the reporter for event logging in libcore 12 EventLogger.setReporter(new EventLoggingReporter()); 13 14 Process.setArgV0("<pre-initialized>"); 15 16 Looper.prepareMainLooper(); 17 18 ActivityThread thread = new ActivityThread(); 19 thread.attach(false); 20 21 if (sMainThreadHandler == null) { 22 sMainThreadHandler = thread.getHandler(); 23 } 24 25 AsyncTask.init(); 26 27 if (false) { 28 Looper.myLooper().setMessageLogging(new 29 LogPrinter(Log.DEBUG, "ActivityThread")); 30 } 31 32 Looper.loop(); 33 34 throw new RuntimeException("Main thread loop unexpectedly exited"); 35
尼玛原来就在16和32行 哎呦好像看到main方法了 这个代码在ActivityThread类中
handler looper messageQueue 之间的关系笔记
标签:
原文地址:http://www.cnblogs.com/lihaolihao/p/4204511.html