Android异步消息处理机制(一)

两个问题:

​ 1、在子线程中如何创建的Handler?需要先做什么?如何发送消息?

​ 2、Handler中发送的消息去哪啦?为什么handleMessage中又能得到这个Message?

首先明确:网络请求必须在子线程中执行,不然会出 NetworkOnMainThreadException 异常。

参考自郭霖android 异步消息处理机制

一、如何在子线程创建Headler

首先我们想在子线程中创建一个Handler。(注意是在子线程中)

在Handler的构造函数中会调用Looper.myLooper() 得到当前的线程的Looper对象,如果没有的话就会报 ” Can’t create handler inside thread that has not called Looper.prepare().“ 这个错误。

prepare() 会先判断sThreadLocal.get() 这个方法从当前线程得到Looper的对象是否为空,如果为空就创建一个,不为空会报“Only one Looper may be created per thread”错误。

ActivityThread的main()方法中,会调用 Looper.prapareMainLooper方法,这其中又会调用 Looper.prepare() 方法,因此主线程中始终有一个Looper对象。

总结一下,普通线程必须先调用Looper.prepare(),然后才能创建Handler对象,

二、Headler发送消息源码解析

创建完Handler之后,只要用把 bundle 放到 Message 中,并且再把 message放到 handler 发送即可。但是这里 Handler 把消息发送到哪里,为什么在 handleMessage 又能得到这个 Message 呢。

除了sendMessageAtFrontOfQueue之外,其他发送消息的方法都会辗转到sendMessageAtTime()中。而入队操作就是在这个sendMessageAtTime() 方法中。

Looper.loop()中包含出队操作,这个方法会一直等待新的消息入队,不然就会进入阻塞状态。每当又一个消息出队 queue.next() ,那就会调用当前handler的dispatchMessage()方法。在dispatchMessage() 方法里就会调用 handleMessage(msg),这样我们在handleMessage就可以得到这个Message了。

MessageQueue 在 Looper 的构造函数中创建,那么一个 Looper 对应了一个 MessageQueue。

一个最标准的异步消息处理线程的写法应该是这样:

class LooperThread extends Thread {  
      public Handler mHandler;  

      public void run() {  
          //先调用Looper.prepare()方法,也就是说必须要有一个 looper 对象。
          Looper.prepare();  

          mHandler = new Handler() {  
              public void handleMessage(Message msg) {  
                  // process incoming messages here  
              }  
          };  
          //调用之后就会一直在MessageQueue中循环遍历Message,如果没有新的消息,就会挂起。
          Looper.loop();  
      }  
  }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值