handlerthread:关于HandlerThread你应该知道的一切

 2021-07-06 17:11    77  

什么是HandlerThread

先来看看官方给的说明

Handy class for starting a new thread that has a looper. The looper can then be used to create handler classes. Note that start() must still be called.

从它的名字 HandlerThread 说明它本质上还是一个Threadhandlerthread,只不过前面加了一个定语Handler。可以猜测这个Thread里包含了一个Handler,有Handler肯定还少不了Looper。

在Android中handlerthread,主线程会自动启动一个Looper去不断的处理消息,启动的代码在 ActivityThread 的 main方法中代码如下:

public static void main(String[] args) { ... Looper.prepareMainLooper(); ... ActivityThread thread = new ActivityThread(); thread.attach(false, startSeq); if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); } if (false) { Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread")); } Looper.loop(); ...}这样系统处理一些消息就可以通过Handler发送消息到Looper的消息队列handlerthread。如果我们也想有这样的一个消息处理系统怎么办呢,答案就是用HandlerThread呀

先来看一下HandlerThread的关键代码

run()

@Overridepublic void run() { mTid = Process.myTid(); Looper.prepare(); synchronized (this) { mLooper = Looper.myLooper(); notifyAll(); } Process.setThreadPriority(mPriority); onLooperPrepared(); Looper.loop(); mTid = -1;}可以看到首先调用了 Looper.prepare() ,然后调用了 Looper.loop() 和主线程启动类似。在Looper.loop()方法中执行了一个for循环,不断从消息队列(MessageQueue)中取出消息处理。

quit()

public boolean quit() { Looper looper = getLooper(); if (looper != null) { looper.quit(); return true; } return false;}quitSafely()

public boolean quitSafely() { Looper looper = getLooper(); if (looper != null) { looper.quitSafely(); return true; } return false;}有两个quit方法,这两个quit方法有什么区别呢?直接看下代码(Looper.java)

public void quit() { mQueue.quit(false);}public void quitSafely() { mQueue.quit(true);}最终调用的都是mQueue.quit方法

void quit(boolean safe) { if (!mQuitAllowed) { throw new IllegalStateException("Main thread not allowed to quit."); } synchronized (this) { if (mQuitting) { return; } mQuitting = true; if (safe) { removeAllFutureMessagesLocked(); } else { removeAllMessagesLocked(); } // We can assume mPtr != 0 because mQuitting was previously false. nativeWake(mPtr); }}可以看到,当直接退出的时候,会把消息队列中所有的消息都取消掉。如果是安全退出,会把延时的消息取消掉,非延时的消息会处理完。有点类似线程池ExecutorService的 shutdown()和 shutdownNow()方法。

Looper 的 quitSafely 方法从 api level 18才可以使用

优点

HandlerThread相比于Thread一次创建线程,就可以不断的处理消息,减少了频繁创建线程带来的资源消耗。

使用场景

满足以下两个场景即可使用HandlerThread

需要子线程处理任务要处理多个任务使用

一个小demo

本文标签:应该

原文链接:https://www.xgfox.com/bcrm/517.html

本文版权:如无特别标注,本站文章均为原创。