您的位置:首页 > 其它

文章标题

2016-06-07 22:32 399 查看

安卓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)这个方法的理解,刚开始这个方法的注释自己也写不出来,但想了好久,终于有点头绪,= =!!。

加油咯,期待下一篇博客!

结束时间 2016-6-7 22:20:07

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: