http://blog.163.com/android_zhouwei/blog/static/1712422672010818105241892/
其实这是我前端时间的研究成果了,放在了我的Msn博客上,但是感觉没人看。所以找到163.com希望和更多人分享。如果刚刚接触Android不久,又刚好想知道这个问题。那么我希望这篇文章能帮助你一丁丁。既然是第一篇文章,所以我还是要先说一下,我也是在2010年8月才进入Android 开发行列的,所以希望多和大家交流交流。好了言归正传吧!
刚接触Handler,有很多疑惑,不知道原理,心里不是滋味。于是想查查资料什么的,发现大家都是相互抄袭转载,而且没有深度,所以决定自己研究我用rose大致的画了1下Handler的流程(如上图):
这里简单的说明一下:某个Acitivty的UiThread启动并创建了1个looper,并调用构造函数looper()初始化包括构造MessageQueue等,并循环开始loop()。这时,我们构建了一个Handler对象,并初始化。当我们调用Handler对象发送消息时,其实只是将Msg 压入自己的队列,而这个队列又是冲looper里获得的(详见Handler的构造),这也是他们关联的原因
疑问:Ui线程的循环?是不是Ui就阻塞了??,也就是Loop()方法的调用应该在研究研究...
这里要涉及到几个类:Handler,Looper,Message,MessageQueue,我们先简单介绍下:
当然免不了要上代码。
Looper:ThreadLocal sThreadLocal;当前线程的副本,获得当前线程的values
MessageQueue mQueue;//消息队列,下面介绍
boolean mRun;//
Thread mThread;//线程
static Looper mMainLooper
public static final void loop() {
Looper me = myLooper();//这个方法是获得当前线程的副本值里,只有Looper,
//return (Looper) sThreadLocal.get();
MessageQueue queue = me.mQueue;//获得Looper里的MsgQueue
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;
}
if (me.mLogging!= null) me.mLogging.println(
">>>>> Dispatching to " + msg.target + " "
+ msg.callback + ": " + msg.what
);
msg.target.dispatchMessage(msg);//通过msg的target对象回调dispatchMessage()
//-->也就是HandlerMessage(),是不是有那么多意思了!
if (me.mLogging!= null) me.mLogging.println(
"<<<<< Finished to " + msg.target + " "
+ msg.callback);
msg.recycle();//处理完的消息回收
}
}
}
public static final void prepare() {//这就告诉了我们,1个线程里只能有1个Looper
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper());//某个线程就设置好了他的Looper
}
private Looper() {//构造函数
mQueue = new MessageQueue();//创建1个消息队列
mRun = true;//表示为run
mThread = Thread.currentThread();//线程初始化为本线程
}
----------------------------------------------------------------------------------------------------------
Handler:的重要成员定义:
public Handler() {
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的静态方法,获得当前线程的Looper;
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = null;
}
Handler发送消息:SendMesasage会调用如下方法:【还有1个方法如出一辙,不与提及】
public boolean sendMessageAtTime(Message msg, long uptimeMillis)
{
boolean sent = false;
MessageQueue queue = mQueue;//获取自己的消息队列:
if (queue != null) {
msg.target = this; //把msg的目标设为自己,也就是说回调自己的方法HandleMessage();
sent = queue.enqueueMessage(msg, uptimeMillis);//把msg压入队列,该队列来自looper,Looper
}
else {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
}
return sent;
}