文章标题
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
相关文章推荐
- Java的字符串String
- SrpingMVC 文件上传容易遇到的问题
- 菜鸟笔记-面向对象
- "选择排序"算法-之通俗易懂原理讲解-java编程
- 班级信息的学生类
- SGU 210. Beloved Sons(二分图匹配)
- Bootstrap 学习之js插件(折叠(collapse)插件)
- 调试报“The source file is different from when the module was built.”问题的解决
- Archetype creation(maven创建模板)
- 判断是否为PE文件改进版
- Swift和Java关于字符串和字符的比较
- 将连接MySQL数据库的java项目程序打包成为.jar格式
- SQL case when
- 3、用私有构造器或者枚举类型强化SIngleton属性
- QSignalMapper简介
- MySQL索引简单总结
- Android N 对Doze(打盹)模式优化
- 219.[Leetcode]Contains Duplicate II
- 用一行简单的代码就能加速IE运行脚本的速度
- 第15周阅读程序(1)