HandlerThread 之于Thread区别以及使用规则

2023-10-24 23:09

本文主要是介绍HandlerThread 之于Thread区别以及使用规则,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

HandlerThread继承于Thread,所以它本质就是个Thread。与普通Thread的差别就在于,它有个Looper成员变量。这个Looper其实就是对消息队列以及队列处理逻辑的封装,简单说就是 消息队列+消息循环。

当我们需要一个工作者线程,而不是把它当作一次性消耗品,用过即废弃的话,就可以使用它。

    private Handler mHandler = null;

    private HandlerThread mHandlerThread = null;

    private void sentRunnableToWorker(Runnable run){

        if (null == mHandlerThread)
        {
            mHandlerThread = new HandlerThread("WorkerThread");

            // 给工作者线程低优先级 
            mHandlerThread.setPriority(Thread.MIN_PRIORITY);
            mHandlerThread.start();
        }

        if (null == mHandler)
            mHandler = new Handler(mHandlerThread.getLooper());

        mHandler.post(run);

    }

AsyncQueryHandler就是基于HandlerThread封装了线程间双向通信,而HandlerThread只做了一半。

 

 

源码分析:

 

  1. public class HandlerThread extends Thread{
  2.           //线程的优先级
  3.            private int mPriority;
  4.           //线程的id
  5.            private int mTid=-1;
  6.            private Looper mLooper;
  7.            public HandlerThread(String name){
  8.                       super(name);
  9.                      //设置优先级为默认线程
  10.                      mPriority=Process.THREAD_PRIORITY_DEFAULT;
  11.            }
  12.            public HandlerThread(String name,int priority){
  13.                       super(name);
  14.                      mPriority=priority;
  15.            }
  16.           //这个如果有需要的话可以继承重写,例如可以在里面声明个Handler 关联此线程。
  17.            protected void onLooperPrepared(){}
  18.            //这个很熟悉吧
  19.            public void run(){
  20.                //得到当前线程的id
  21.                 mTid=Process.myTid;
  22.                //一旦调用这句代码,就在此线程中创建了Looper 对象。这就是为什么我们要在调用线程的start()方法后
  23.                //才能得到Looper 对象即 当 调用Looper.myLooper()时不为Null。
  24.                 Looper.prepare();
  25.                 //同步代码块,意思就是当获得mLooper对象后,唤醒所有线程。(会在以后的例子中有所体现)
  26.                synchronized(this){
  27.                      mLooper=Looper.myLooper();
  28.                      notifyAll();
  29.                }
  30.               //设置线程的优先级
  31.                Process.setThreadPriority(mPriority);
  32.              //调用上面的方法(需要用户重写)
  33.               onLooperPrepared();
  34.                //建立了消息循环
  35.                 Looper.loop();
  36.                mTid=-1;
  37.            }
  38.            public Looper getLooper(){
  39.                     //线程死了,那就只有NULL了。
  40.                      if(!isAlive()){
  41.                         return null;
  42.                     }
  43.             //看见没,又是同步代码块,正好和上面的形成对应,就是说只要线程活着并且我的looper为NULL,那么我就让你一直等。。。
  44.                    synchronized(this){
  45.                           while(isAlive()&&mLooper==null){
  46.                                try{
  47.                                          wait();
  48.                                    }catch(InterruptedException e){}
  49.                           }
  50.                    }
  51.                              return mLooper;
  52.            }
  53.           public boolean quit(){
  54.               Looper looper =getLooper();
  55.                if(looper!=null){
  56.                   //退出消息循环
  57.                    looper.quit();
  58.                    return true;
  59.               }
  60.               return false;
  61.        }
  62.          //返回线程ID
  63.          public int getThreadId(){
  64.                return mTid;
  65.         }
  66. }
复制代码

整体来说代码还是比较浅显易懂的。主要的作用是建立了一个线程,并且创立了消息队列,有来自己的looper,可以让我们在自己的线程中分发和处理消息。具体的使用示例,我会在下一帖中体现。还有要说明的是handler 与谁相关联不是看声明在什么地方,是看与哪个线程的looper挂钩。默认是主线程的looper.因为主线程中默认就有了looper,消息循环队列。

每天进步一点点之AsyncQueryHandler学习

AsyncQueryHandler:异步的查询操作帮助类,其实它同样可以处理增删改

1。AsyncQueryHandler的作用

查询其API便可知,它担供:

startInsert

startDelete

startUpdate

startQuery

这四个操作,并提供相对应的onXXXComplete方法,以供操作完数据库后进行其它的操作,这四个onXXXComplete方法都是空实现,以便我们只需要去实现我们关注的操作。

 

2。为什么要使用AsyncQueryHandler

当然你也可以使用ContentProvider去操作数据库。

这在数据量很小的时候是没有问题的,但是如果数据量大了,可能导致UI线程发生ANR事件。

当然你也可以写个Handler去做这些操作,只是你每次使用ContentProvider时都要再写个Handler,必然降低了效率。

因此API提供了一个操作数据库的通用方法。

 

3。如何使用AsyncQueryHandler

你只需要继承AsyncQueryHandler类,并提供onXXXComplete方法的实现(可以实现任何一个或多个,当然你也可以一个也不实现,如果你不关注操作数据库的結果),在你的实现中做一些对数据库操作完成的处理。

使用时直接调用startXXX方法即可。传入的通用参数如下:

int token,一个令牌,需要跟onXXXComplete方法传入的一致。(当然你也可以不一致,同样在数据库的操作结束后会调用对应的onXXXComplete方法 )

Object cookie,你想传给onXXXComplete方法使用的一个对象。(没有的话传递null即可。基本发现这个变量没太大作用)

Uri uri,(不解释)

 

4。AsyncQueryHandler还为我们做了什么

AsyncQueryHandler中使用了一个WeakReference<ContentResolver>对象,即ContentResolver的弱引用  作用:当contentProvied发生变化时候同步更新仍可以通过使用AsyncQueryHandler类来达到这一要求(暂时还没理解这个作用)

同时,在它执行操作数据库时,吃掉了所有的异常。见如下代码。

 catch (Exception e) {
                        Log.w(TAG, e.toString());
                        cursor = null;
 }

这篇关于HandlerThread 之于Thread区别以及使用规则的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/278377

相关文章

C++变换迭代器使用方法小结

《C++变换迭代器使用方法小结》本文主要介绍了C++变换迭代器使用方法小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1、源码2、代码解析代码解析:transform_iterator1. transform_iterat

C++中std::distance使用方法示例

《C++中std::distance使用方法示例》std::distance是C++标准库中的一个函数,用于计算两个迭代器之间的距离,本文主要介绍了C++中std::distance使用方法示例,具... 目录语法使用方式解释示例输出:其他说明:总结std::distance&n编程bsp;是 C++ 标准

vue使用docxtemplater导出word

《vue使用docxtemplater导出word》docxtemplater是一种邮件合并工具,以编程方式使用并处理条件、循环,并且可以扩展以插入任何内容,下面我们来看看如何使用docxtempl... 目录docxtemplatervue使用docxtemplater导出word安装常用语法 封装导出方

Linux换行符的使用方法详解

《Linux换行符的使用方法详解》本文介绍了Linux中常用的换行符LF及其在文件中的表示,展示了如何使用sed命令替换换行符,并列举了与换行符处理相关的Linux命令,通过代码讲解的非常详细,需要的... 目录简介检测文件中的换行符使用 cat -A 查看换行符使用 od -c 检查字符换行符格式转换将

使用Jackson进行JSON生成与解析的新手指南

《使用Jackson进行JSON生成与解析的新手指南》这篇文章主要为大家详细介绍了如何使用Jackson进行JSON生成与解析处理,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 核心依赖2. 基础用法2.1 对象转 jsON(序列化)2.2 JSON 转对象(反序列化)3.

Springboot @Autowired和@Resource的区别解析

《Springboot@Autowired和@Resource的区别解析》@Resource是JDK提供的注解,只是Spring在实现上提供了这个注解的功能支持,本文给大家介绍Springboot@... 目录【一】定义【1】@Autowired【2】@Resource【二】区别【1】包含的属性不同【2】@

使用Python实现快速搭建本地HTTP服务器

《使用Python实现快速搭建本地HTTP服务器》:本文主要介绍如何使用Python快速搭建本地HTTP服务器,轻松实现一键HTTP文件共享,同时结合二维码技术,让访问更简单,感兴趣的小伙伴可以了... 目录1. 概述2. 快速搭建 HTTP 文件共享服务2.1 核心思路2.2 代码实现2.3 代码解读3.

Elasticsearch 在 Java 中的使用教程

《Elasticsearch在Java中的使用教程》Elasticsearch是一个分布式搜索和分析引擎,基于ApacheLucene构建,能够实现实时数据的存储、搜索、和分析,它广泛应用于全文... 目录1. Elasticsearch 简介2. 环境准备2.1 安装 Elasticsearch2.2 J

使用C#代码在PDF文档中添加、删除和替换图片

《使用C#代码在PDF文档中添加、删除和替换图片》在当今数字化文档处理场景中,动态操作PDF文档中的图像已成为企业级应用开发的核心需求之一,本文将介绍如何在.NET平台使用C#代码在PDF文档中添加、... 目录引言用C#添加图片到PDF文档用C#删除PDF文档中的图片用C#替换PDF文档中的图片引言在当

Java中的String.valueOf()和toString()方法区别小结

《Java中的String.valueOf()和toString()方法区别小结》字符串操作是开发者日常编程任务中不可或缺的一部分,转换为字符串是一种常见需求,其中最常见的就是String.value... 目录String.valueOf()方法方法定义方法实现使用示例使用场景toString()方法方法