安卓编程吧 关注:34,859贴子:335,668
  • 7回复贴,共1

【每日推荐文章】从源码角度深入理解Handler

只看楼主收藏回复

为了获得良好的用户体验,Android不允许开发者在UI线程中调用耗时操作,否则会报ANR异常,
很多时候,比如我们要去网络请求数据,或者遍历本地文件夹都需要我们在新线程中来完成,新线程中不能更新UI,
一个常规的解决方法就是在主线程中实例化一个Handler,
在新线程中将消息封装在一个Message中,发送到主线程中,然后主线程来更新界面。
这些都很简单,我们就不多说了,今天我主要想通过阅读源码来理解Handler,Looper之间的关系。
原文地址:http://blog.csdn.net/u012702547/article/details/49227213


IP属地:福建1楼2015-10-18 18:30回复
    缘起
    促使我去看Handler源码是由于在公司的开发中遇到的一个问题,
    一位同事在一个非UI线程中实例化Handler,结果程序一启动就崩溃,
    当时来问我,我以前也没遇到过,不知道是什么原因,
    但是我发现这个问题是由于新线程导致的,就是不能在新线程中创建Handler,
    但是究竟是什么原因,当时并没有发现。


    IP属地:福建2楼2015-10-18 18:33
    回复
      上下求索
      这周时间充裕,决定看一下原因,通过阅读源码来彻底了解Handler的工作机制。
      首先,会崩溃的代码是这样的:

      报错信息:

      说是Can’t create handler inside thread that has not called Looper.prepare(),
      就是说呀不能在没有调用Looper.prepare的线程中创建Handler,
      那么我们在创建之前如果调用Looper.prepared(),结果又会怎么样呢?


      IP属地:福建3楼2015-10-18 18:35
      回复
        好吧,那么就在创建Handler之前加上一句Looper.prepared(),这个时候应用不崩溃了,而且日志也能如期打印出来。
        那么Looper.prepare()究竟做了什么?我们先来看看Handler的构造方法。
        public Handler() {
        this(null, false);
        }


        IP属地:福建4楼2015-10-18 18:37
        回复
          看代码之前我们先来看看注释,
          说是默认的构造方法将这个Handler与当前的Thread关联,
          如果当前的Thread没有一个Looper,那么这个Handler不能接收消息,会抛出一个异常。
          然后看看代码,
          还是很简单的,只有一句,this(null,false);
          这是调用了另外一个有两个参数的构造方法,
          那我们就再看看这个有两个参数的构造函数:


          IP属地:福建5楼2015-10-18 18:39
          回复
            转载到此,详细看原文:http://blog.csdn.net/u012702547/article/details/49227213
            觉得有意义就顶个贴。


            IP属地:福建6楼2015-10-18 18:40
            回复
              up


              7楼2015-10-19 13:28
              回复
                理解原理!!


                8楼2015-10-19 16:33
                回复