关于HandlerThread你应该知道的一切

什么是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 说明它本质上还是一个Thread,只不过前面加了一个定语Handler。可以猜测这个Thread里包含了一个Handler,有Handler肯定还少不了Looper

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


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的关键代码

run()
@Override
public 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);
    }
}

可以看到,当直接退出的时候,会把消息队列中所有的消息都取消掉。如果是安全退出,会把延时的消息取消掉,非延时的消息会处理完。有点类似线程池ExecutorServiceshutdown()shutdownNow()方法。

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

优点

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

使用场景

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

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

一个小demo
https://github.com/77Y/HandlerThread

关注微信公众号,最新技术干货实时推送

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值