文章标题

安卓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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值