HandlerThread原理与应用
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HandlerThread原理与应用相关的知识,希望对你有一定的参考价值。
参考技术A 在理解了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吗?【英文标题】:Necessary to quit a HandlerThread? 【发布时间】:2011-09-26 10:34:04 【问题描述】:我的应用程序使用HandlerThread
进行一些跨组件共享的操作,这些操作需要在后台线程上运行。大多数情况下,该线程将处于等待状态。
我可以让这个HandlerThread
在我的应用程序中运行(等待),在必要时向它发送消息,但从不通过HandlerThread.getLooper().quit()
退出它吗?这可能意味着这个HandlerThread
将继续处于等待状态,即使在我的所有应用程序组件都被销毁之后。
起初,这对我来说似乎是一个很大的拒绝——我绝对不想这样做——但我现在不确定。当 Android 杀死我的进程时,就像它需要释放 CPU 时间或内存时一样,它会结束这个线程以及我的 UI 线程。此外,线程将等待,因此不会消耗任何 CPU 时间。除此之外,我的应用程序使用了许多AsyncTasks
,我知道它们使用了一个线程池。据我了解,AsyncTask
使用了ThreadPoolExecutor
,它不遵循任何应用程序生命周期回调(池中的线程在不使用时,只是坐等)。
所以我的问题是,我能否在多个应用程序组件中使用 HandlerThread
,从不(或很少)退出它,并在不使用时让它等待,而不会遭受可怕的不良影响?
【问题讨论】:
【参考方案1】:我个人的偏好是在需要时创建一个新线程,并在完成后清理它。这样,多个组件尝试同时使用同一个线程时我不会遇到任何问题,并且我保持“干净的船”。 Android 也有很好的AsyncTask,这让你很容易。
话虽如此,我认为您没有理由不能为多个组件重用您的处理程序线程,只要您规范对线程的访问并在您的活动被销毁时正确清理它。如果我正确理解this post,即使您的所有活动都已终止,您的线程也可能会继续运行,因为您的进程可能会继续运行。为了解决这个问题,您可以将您的线程设置为守护线程。当应用程序中的最后一个非守护线程完成后,守护线程会自动销毁。
顺便说一句,您也可以考虑使用ThreadPoolExecutor
【讨论】:
我不同意你的观点,因为如果你必须在另一个线程上做的事情做了很多次,会创建很多线程,这可能会导致应用程序崩溃。 是和不是。如果您有许多并行操作,那么您是对的,最好重用 1 个(或几个)线程。如果它是您的应用程序系列中的相同操作,您可以采用任何一种方式。只要您正确清理线程,您的应用程序就不会崩溃。在我的应用程序中,相同的操作仅每 x 分钟执行一次,因此销毁线程更容易且对内存更友好。以上是关于HandlerThread原理与应用的主要内容,如果未能解决你的问题,请参考以下文章
Handler,Looper,HandlerThread浅析
Android培训HandlerThread的使用及源码解析