安卓Handler
开始时间2016-6-6 20:38:52
从来没写过博客,虽然一直也想开始写博客,但由于自己的各种原因,一直都拖着,也就是懒!!!
写这篇博客的意义在于让自己学习到的一些知识积累起来,让自己能更好的理解,如果从中能得到别人的指点或者对别人也有帮助,那样就更好了。
之前看到Van前辈分享的一篇文章,印象一直很深刻,文中说到,”android的功夫,在android之外,这是理解android源码的道”,一直也想不明白Van前辈所说的”道”是什么,想不明白的原因是自己的道行不够,虽然自己也一直想寻找自己的”道”,但一直也没找到,但自己始终相信追随大牛的脚步,学习大牛的步伐,一定可以让自己成长的更快。
也还记得Van前辈说过,”先有问题,后有代码,这是理解android的术”,自己也一直在想,什么又是”术”,查找了下资料,术者,道之用也。
今天写的这篇博客是关于Handler,虽然自己觉得自己也理解了,但大牛都说自己理解跟写出博客让人是不一样的。所以自己也想尝试下,或许能找到自己的道术。
“先有问题”
为什么会有Handler?Handler是为了解决子线程能够更改UI,那子线程为什么不能更改UI呢?子线程更改UI可能会导致UI出现不可预估的情况,(这又涉及到多线程的问题了,这个以后有机会在写),我们都知道,可以用锁解决啊,加锁有两个缺点,一是UI访问的逻辑变得复杂(不理解),二是效率会降低(锁的机制以后有机会在写)。
Handler出现的意义在哪?这是Google提供给我们用的接口,方便我们开发。
Handler的做法是?通过子线程发出消息(我们去商场买的东西),添加到消息队列MessageQueue(好多人,得排队吧),主线程的Looper(付款时的售货员,轮到谁付款就帮谁处理,没人时我就等待咯)
“后有代码”
我们就通过通过sendMessage(Message msg)介绍,其它形式差不多
1、public final boolean sendMessage(Message msg)
{
return sendMessageDelayed(msg, 0);
}2、public final boolean sendMessageDelayed(Message msg, long delayMillis)
{
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}//uptimeMillis用在MessageQueue中,作为排队的先后顺序(下面详谈),queue我们先理解成主线程已经帮我们初始化好了
3、public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
MessageQueue queue = mQueue;
return enqueueMessage(queue, msg, uptimeMillis);
}//msg.target = this;this表示当前的Handler,msg.target表示这条属于是谁发过来的
4、private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}//把消息加入队列中,按时间的先后顺序,假如我们添加了一个消息是s1,sendEmptyMessageDelayed(1,1000),因为这是第一个消息,所以mMessages为null,然后进入if(),此时mMessages等于当前的s1,msg.next = null。假如我们又马上添加了一个s2,sendEmptyMessageDelayed(1,3000),判断不成立进入else,因为p为s1,而s1.next为null,退出for(,,),s1.next=s2,s2.next=null,假如我们又马上添加了一个s3,sendEmptyMessageDelayed(1,2000),判断不成立进入else,prev为s1,p为s2,而s3.when=2000 < s2.when = 3000,s1.next=s2,s2.next=s3,从而达到按时间顺序排序的作用
5、 boolean enqueueMessage(Message msg, long when) {
synchronized (this) {
msg.when = when;
Message p = mMessages;
if (p == null || when == 0 || when < p.when) {
// New head, wake up the event queue if blocked.
msg.next = p;
mMessages = msg;
needWake = mBlocked;
} else {
Message prev;
for (;;) {
prev = p;
p = p.next;
if (p == null || when < p.when) {
break;
}
if (needWake && p.isAsynchronous()) {
needWake = false;
}
}
msg.next = p; // invariant: p == prev.next
prev.next = msg;
}
return true;
}
}//取到消息并返回消息
6、Message next() {
if (prevMsg != null) {
prevMsg.next = msg.next;
} else {
mMessages = msg.next;
}
msg.next = null;
msg.markInUse();
return msg;
}//主线程的轮询器,取到消息后就dispatchMessage(msg)
7、public static void loop() {
final MessageQueue queue = me.mQueue;
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
return;
}
msg.target.dispatchMessage(msg);
msg.recycle();
}
}//最终的处理消息
8、public void dispatchMessage(Message msg) {
handleMessage(msg);
}
OnPause 2016-6-6 22:29:13 第五点注释还没写
OnResume 2016-6-7 19:09:18
终于粗略的写完了这篇博客,其实handler包括的东西远远不止这些。
写完这篇让我印象比较深的是enqueueMessage(Message msg, long when)这个方法的理解,刚开始这个方法的注释自己也写不出来,但想了好久,终于有点头绪,= =!!。
加油咯,期待下一篇博客!