handlerthread(handlerthread优缺点)

http://www.itjxue.com  2023-01-28 14:20  来源:未知  点击次数: 

HandlerThread原理与应用

?在理解了Handler的原理之后,我们知道在一个子线程中创建一个Handler不能缺少了Looper.prepare()和Looper.loop()两个方法,具体的原因这里不再赘述,不熟悉原理的可以先看下另一篇文章 Handler的原理解析 .

本篇文章主要是讲解HandlerThread的使用的。

?首先HandlerThread是继承于Thread类的,所以本质上HandlerThread就是一个线程,接下来就详细的去看一看,这是怎样的一个线程?

?首先,先看下它的构造函数:

?既然是线程,那么最重要的当然是run方法来,看完了run方法,相信你也就明白HandlerThread的用途了!

?怎么样,这是不是和我们之前在子线程中创建Handler一样,首先是Looper.prepare(),接着是new Handler(), 最后是Looper.loop()。等等,这里并没有创建Handler啊!别急,我们先一步一步地看看run方法再说为什么没有创建Handler。

?通过查找发现到一个getLooper()的方法,该方法返回了当前线程的mLooper对象,还记得Looper是在哪里进行赋值的吗?在线程的run方法里,所以当线程启动之后才能创建Looper并赋值给mLooper,这里的阻塞就是为了等待Looper的创建成功。同时该方法是用Public修饰的,说明该方法是提供外部调用的,Looper创建成功提供给外部使用。

?最后在对象销毁前,调用下面的方法退出Looper循环

?quit方法实际是调用MessagQueue的removeAllMessagesLocked,移除所有延迟和非延迟的消息,

?quitSafely方法调用的是removeAllFutureMessagesLocked方法,该方法只清除延迟的消息,非延迟的消息

还是会进行分发处理。

?HandlerThread分析完啦,是不是有点蒙,自始至终都没有出现Handler,HandlerThread要怎么用呢?

?下面我们就通过一个Demo来说明下HandlerThread是怎么用的?

handlerthread会泄漏吗

你好,handlerthread是会泄漏的

什么是java的内存泄漏?

Java内存泄漏指的是进程中某些对象已经没有使用价值并且想将其释放回收掉,但是它们却可以直接或间接地被其他对象强引用,导致无法被GC回收。无用的对象占据着内存空间,使得实际可使用内存变小,形象地说法就是内存泄漏。

为什么我们上面的代码会产生内存泄漏?

1、在程序启动的时候就在主线程中创建了一个Looper 对象,它内部维护着一个消息队列,并且一条一条的对消息进行处理。?

2、当我们发送消息的时候,在Message的target里面存放着发送该消息的handler对象,即消息里面包含了一个Handler实例的引用,并且就是通过这个handler实例来回调handleMessage方法进行处理。?

如果对上面两点不明白的话,可以看看Looper与Handler解析?

3、在Java中,非静态的内部类和匿名内部类都会隐式地持有其外部类的引用。静态的内部类不会持有外部类的引用。?

理解了上面的三点,应该就差不多清楚了为什么上面的代码会出现内存泄漏。

如何解决这个问题??

也很简单,上面说到要避免使用非静态的内部类,那我们就使用静态的内部类,或者把内部类单独写个文件,让它成为一个单独的类。另外,我们可以在里面增加一个成员变量来弱引用外部类实例,就可以调用外部类的方法。?

第一种改进方法:使用静态内部类

第二种改进方法:单独定义一个类

希望对你有帮助

Android中的特殊线程——HandlerThread

一般我们想要执行耗时操作都会想开启Thread子线程去处理,但是多次创建和销毁线程是很耗系统资源的。为了解决这一问题,我们可以自己构建一个循环线程,在线程当中创建一个Looper轮循器,来进行消息的轮循, 当有耗时任务需要投放到该循环线程时,线程就会执行耗时任务,任务执行完成之后,线程又会处于阻塞等待状态,不会马上销毁掉,直到下一个耗时任务被投放进来;即通过阻塞和等待来保证性能最优,为此Google为我们封装好了HandlerThread框架。

HandlerThread本质上就是一个Thread子线程,不同的是在Thread内部有一个Looper开启了轮循器;

HandlerThread = Handler + Thread + Looper

由于一般的Thread没有开启Looper轮循器,所以不能在子线程中创建handler,因为没有对应的MessageQueue与handler相关联,而MessageQueue是由Looper进行维护的;如果想在子线程中创建handler,必须先通过Looper.prepare()创建一个Looper,再通过Looper.loop()开启循环,才能使用Handler。

1、HandlerThread本质上是一个线程类,继承了Thread;

2、HandlerThread有自己的内部Looper对象,可以进行loop循环;所以在HandlerThread中可以创建handler来发送和处理消息;

3、通过获取HandlerThread的Looper对象传递给Handler,可以在handleMessage()中执行异步操作;

4、handler中的looper默认绑定了UI线程的MessageQueue,对于非UI线程想使用MessageQueue机制的,HandlerThread的内部Looper最适合,它不会干扰和阻塞UI线程,减少了对性能的消耗,但是处理效率低;

5、HandlerThread是一个串行队列,会比较稳定;

Android线程之HandlerThread

HandlerThread是Thread的一个子类,是Android中提供的另一种线程形态。

我擦,有线程、有looper这不正是我们当初声称在子线程中构建handler消息系统的所需要的吗?

那很明显,这个 HandlerThread 的目的就是让我们创建一个 Handler ,然后所有的任务操作成功的转给了 Handler 来处理完成。

但注意的是这个 Handler 的消息处理是运行在子线程中的。

在主线程中创建 handler ,简单的模拟一下 HandlerThread 工作原理

由于这个handler回调是运行在子线程中的,因此如果你想要更新UI可以借助主线程的默认的looper来实现,这个问题又愉快的转化到了子线程更新UI的问题。

HandlerThread其本质就是一个线程,只不过这个线程加入了Handler消息异步处理的机制。

那这与普通的创建线程的好处是什么呢?

HandlerThread 之简单理解与使用

HandlerThread 顾名思义就是一种可以使用 Handler 的 Thread。日常开发中我们经常会通过创建一个 Thread 去执行任务,有多个任务就多创建几个线程实现,这时候可能出现线程同步的问题。不过有时候我们并不需要很强的并发性,只需保证按照顺序地执行各个任务即可,有什么好办法实现呢?第一反应想到的可能是通过 Executors.newSingleThreadExecutor() 方法来创建一个 SingleThreadExecutor,来统一所有的任务到一个线程中,然后按顺序执行。其实,除了这个方法之外,HandlerThread 也可以实现。

首先创建一个 HandlerThreadActivity

快速三击按钮,打印日志如下:

可以发现,三次不同的任务按开始的顺序执行,而且是运行在子线程中,那到底是怎么实现的呢?

通读下来,如果熟悉 Handler 原理 的同学大概就明白 HandlerThread 的机制了:

这就是 HandlerThread 的大概原理啦,它在 Android 中的一个具体的使用场景是 IntentService,有兴趣了解 IntentService 的 可以点击这里 。

惯例附上 ---Demo源码---

(责任编辑:IT教学网)

更多

相关业界动态文章