之前已经了解Handler的一些知识,今天主要研究Google封装的实现线程通信的一个类HandlerThread。

一、HandlerThread使用

  1. @Override
  2. protected void onCreate(Bundle savedInstanceState) {
  3. ......
  4. HandlerThread handlerThread = new HandlerThread("handler-thread");
  5. handlerThread.start();
  6.  
  7. mHandler = new Handler(handlerThread.getLooper()){
  8. @Override
  9. public void handleMessage(Message msg) {
  10. //这里已经不是在主线程,而是在HandlerThread线程中了
  11. super.handleMessage(msg);
  12. }
  13. };
  14. //主线程向子线程发送消息
  15. mHandler.sendEmptyMessage(100);
  16. }
  1. new一个HandlerThread并启动
  2. 实例化Handler并获取HandlerThread的Looper
  3. 可以在任何地方使用handler发送消息,handler里面实现是异步的

HandlerThread简单的替代了之前研究过的一段代码,如下:

  1. Thread mThread = new Thread(new Runnable() {
  2. @Override
  3. public void run() {
  4. Looper.prepare();
  5. mHandler = new Handler(){
  6. @Override
  7. public void handleMessage(Message msg) {
  8. ......
  9. super.handleMessage(msg);
  10. }
  11. };
  12. Looper.loop();
  13. }
  14. });

这样替代后我们不用自己去实现Thread,来执行耗时操作。

HandlerThread本身是一个Thread,在里面做了一个消息循环的管道,Handler往里面扔消息,并得到消息进行处理。

对比上面两个mHandler,我们可以发现其构造方法不一样,一个没有传Looper,通过Handler源码可以发现是使用当前线程的Looper,一个有,用的就是HandlerThread的Looper。

  1. public Handler(Looper looper, Callback callback, boolean async) {
  2. mLooper = looper;
  3. mQueue = looper.mQueue;
  4. mCallback = callback;
  5. mAsynchronous = async;
  6. }

上述只是Handler其中一个构造方法,传Looper的类会最终走到这个构造方法中,有两个参数需要注意1、mLooper 2、mQueue

Handler在构建的时候就拿到Looper和MessageQueue,传输消息机制就是很容易理解了。

没有传Looper的构造方法只是把mLooper = looper 换成了mLooper = Looper.myLooper()。

二、源码分析

  1. @Override
  2. public void run() {
  3. mTid = Process.myTid();
  4. Looper.prepare();
  5. synchronized (this) {
  6. mLooper = Looper.myLooper();
  7. notifyAll();
  8. }
  9. Process.setThreadPriority(mPriority);
  10. onLooperPrepared();
  11. Looper.loop();
  12. mTid = -;
  13. }
  14.  
  15. public Looper getLooper() {
  16. if (!isAlive()) {
  17. return null;
  18. }
  19.  
  20. // If the thread has been started, wait until the looper has been created.
  21. synchronized (this) {
  22. while (isAlive() && mLooper == null) {
  23. try {
  24. wait();
  25. } catch (InterruptedException e) {
  26. }
  27. }
  28. }
  29. return mLooper;
  30. }

以上代码是HandlerThread主要的代码,我们可以看见run方法中构建了Looper的消息循环,并没有Handler,可以说HandlerThread就是一个加了消息循环的Thread,在这里看起来和Handler并没有什么关系。

我们在使用的时候才会把Handler和HandlerThread的Looper绑定在一起,构建成一个完整的消息传递系统。

HandlerThread学习的更多相关文章

  1. IntentService学习

    IntentService是一个Service,主要就是Service和HandlerThread的结合 一.使用 不用多说和使用Service差不多,但是比Service多个一个方法实现: publ ...

  2. Android(java)学习笔记265:Android线程形态之 HandlerThread

    1.  HandlerThread Android HandlerThread 完全解析 Handler与HandlerThread区别,HandlerThread应用(对比AsyncTask) 备注 ...

  3. HandlerThread 类的学习(转载)

    HandlerThread继承于Thread,所以它本质就是个Thread.HandlerThread类用于方便的创建一个含有looper的线程类,looper用来创建handler类.我们一般不创建 ...

  4. Android(java)学习笔记209:Android线程形态之 HandlerThread

    1.  HandlerThread Android HandlerThread 完全解析 Handler与HandlerThread区别,HandlerThread应用(对比AsyncTask) 备注 ...

  5. HandlerThread源码分析

    其实原本HandlerThread的分析不应该单独开一篇博客的,应该在讲消息机制的那一片中一起分析. 但当时忘记了,而且今天第一次用MarkDown写博客,有点上瘾,就再来一篇,权当滥竽充数过过手瘾. ...

  6. Android HandlerThread 的使用及其Demo

    今天我们一起来学习下一个Android中比较简单的类HandlerThread,虽然它的初始化有点小麻烦. 介绍 首先我们来看看为什么我们要使用HandlerThread?在我们的应用程序当中为了实现 ...

  7. 【Android】IntentService & HandlerThread源码解析

    一.前言 在学习Service的时候,我们一定会知道IntentService:官方文档不止一次强调,Service本身是运行在主线程中的(详见:[Android]Service),而主线程中是不适合 ...

  8. Android 服务类Service 的详细学习

    http://blog.csdn.net/vipzjyno1/article/details/26004831 Android服务类Service学习四大组建   目录(?)[+] 什么是服务 服务有 ...

  9. Android(java)学习笔记202:Handler消息机制的原理和实现

     联合学习 Android 异步消息处理机制 让你深入理解 Looper.Handler.Message三者关系   1. 首先我们通过一个实例案例来引出一个异常: (1)布局文件activity_m ...

随机推荐

  1. css预处理语言--让你的css编写更加简单方便

    CSS预处理语言之一-------LESS Less 是一门 CSS 预处理语言,它扩展了 CSS 语言,增加了变量.Mixin.函数等特性,使 CSS 更易维护和扩展. Less 可以运行在 Nod ...

  2. spring boot / cloud (十八) 使用docker快速搭建本地环境

    spring boot / cloud (十八) 使用docker快速搭建本地环境 在平时的开发中工作中,环境的搭建其实一直都是一个很麻烦的事情 特别是现在,系统越来越复杂,所需要连接的一些中间件也越 ...

  3. JSTL之c:set

    <jsp:setProperty>标记只能用来做一件事,那就是设置bean的性质. 但是,如果你想设置一个Map中的值呢?或者说想在Map中创建新的一项呢?或者只是希望创建一个新的请求作用 ...

  4. hdu 5937 -- Equation(搜索)

    题目链接 problem description Little Ruins is a studious boy, recently he learned addition operation! He ...

  5. Perfect Pth Powers poj1730

    Perfect Pth Powers Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16383   Accepted: 37 ...

  6. 郑厂长系列故事——排兵布阵 hdu4539(状态压缩DP)

    郑厂长系列故事——排兵布阵 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)To ...

  7. python---os模块使用详解

    os模块调用操作系统接口的模块 相关方法或属性: getcwd() --- 获取当前的操作目录,等同于linux中的pwd命令. 调用:os.getcwd() chdir() --- 改变python ...

  8. python识别验证码——一般的数字加字母验证码识别

    1.验证码的识别是有针对性的,不同的系统.应用的验证码区别有大有小,只要处理好图片,利用好pytesseract,一般的验证码都可以识别 2.我在识别验证码的路上走了很多弯路,重点应该放在怎么把图片处 ...

  9. Rx 入门指引 (一)

    自学 Rx 快有一个周了, 它非常适合处理复杂的异步场景.结合自己所学,决定写系列教程. 我认为, Rx 中强大的地方在于两处 管道思想,通过管道,我们订阅了数据的来源,并在数据源更新时响应 . 强大 ...

  10. Oracle 定时查询数据插入新表中(job+存储过程)

    create table EGMAS_COUNT_DATA(TIMES       date not null, COUNT NUMBER(30) not null, SYSTEM_NAME VARC ...