首页互联网handlerthread(HandlerThread详解)

handlerthread(HandlerThread详解)

编程之家2024-01-28105次浏览

一、HandlerThread原理与应用

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

handlerthread(HandlerThread详解)

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

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

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

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

handlerthread(HandlerThread详解)

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

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

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

handlerthread(HandlerThread详解)

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

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

还是会进行分发处理。

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

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

二、Android线程之HandlerThread

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

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

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

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

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

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

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

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

三、handlerthread会泄漏吗

你好,handlerthread是会泄漏的

什么是java的内存泄漏

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

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

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

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

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

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

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

如何解决这个问题?

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

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

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

希望对你有帮助

游戏服务器防御(游戏服务器防御攻击怎么设置)sourceinsight3.5注册码(SourceInsight3.5序列号)