Android HandlerThread 详解

请支持原创~~

版本基于:Android R

前言:

Android 基于Handler 剖析消息机制 中剖析了Handler为基础的消息通信机制, Android 中Handler 详解 中大体说了一下handler的应用过程,android 提供了HandlerThread,更好的可以为多线程的应用场景服务。

比较 Android AsyncTask 详解 ,HandlerThread 提供了长期的Thread,支持各种消息传递、处理,而无需像AsyncTask 每次都需要重新创建、execute。

源码解析:

/**
 * A {@link Thread} that has a {@link Looper}.
 * The {@link Looper} can then be used to create {@link Handler}s.
 * <p>
 * Note that just like with a regular {@link Thread}, {@link #start()} must still be called.
 */

通过注释可以看出:

  • HandlerThread 是一个拥有自己Looper 的Thread;
  • HandlerThread 可以通过Looper创建Handler,用以msg 的发送和处理;
  • HandlerThread 是个Thread,执行时需要先调用start();

构造:

public class HandlerThread extends Thread {
    int mPriority;
    int mTid = -1;
    Looper mLooper;
    private @Nullable Handler mHandler;

    public HandlerThread(String name) {
        super(name);
        mPriority = Process.THREAD_PRIORITY_DEFAULT;
    }

    public HandlerThread(String name, int priority) {
        super(name);
        mPriority = priority;
    }

Thread 的priority 可以外面指定,也可以使用默认优先级,默认优先级值为0;

start():

HandlerThread 在使用的时候需要调用start函数,用以完成初始化工作。

    @Override
    public void run() {
        mTid = Process.myTid();
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();
        mTid = -1;
    }

getLooper():

在新建实例之后,必须要start 才能能应用,不然在getLooper的时候:

public Looper getLooper() {
    if (!isAlive()) {
        return null;
    }
    
    // If the thread has been started, wait until the looper has been created.
    synchronized (this) {
        while (isAlive() && mLooper == null) {
            try {
                wait();
            } catch (InterruptedException e) {
            }
        }
    }
    return mLooper;
}

会认为不是alive,返回null。

所以一般应用过程是这样的:

//创建一个HandlerThread,即创建了一个包含Looper的线程。
    HandlerThread handlerThread = new HandlerThread("leochin.com");
    handlerThread.start(); //创建HandlerThread后一定要记得start()
//获取HandlerThread的Looper
    Looper looper = handlerThread.getLooper();
//创建Handler,通过Looper初始化
    Handler handler = new Handler(looper);

quit 和 quitSafely:

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

    public boolean quitSafely() {
        Looper looper = getLooper();
        if (looper != null) {
            looper.quitSafely();
            return true;
        }
        return false;
    }
  • safe 模式下会判断将没有处理的msg recycle掉,已经在处理的,会等到处理完成;
  • 非safe模式下则不会check,直接全部recycle 掉;

举例

(copy 于Android TV):

    public TvInputBaseSession(Context context, String inputId, int deviceId) {
        super(context);
        mInputId = inputId;
        mDeviceId = deviceId;
        mTvInputManager = (TvInputManager)context.getSystemService(Context.TV_INPUT_SERVICE);
        mHardware = mTvInputManager.acquireTvInputHardware(deviceId,
                mHardwareCallback, mTvInputManager.getTvInputInfo(inputId));
        initThread(mInputId);
    }

    private void initThread(String inputId) {
        mHandlerThread = new HandlerThread(inputId);
        mHandlerThread.start();
        mSessionHandler = new Handler(mHandlerThread.getLooper(), this);
    }

    private void releaseThread() {
        mHandlerThread.quit();
        mHandlerThread = null;
        mSessionHandler = null;
    }

    @Override
    public boolean handleMessage(Message msg) {
        if (DEBUG)
            Log.d(TAG, "==== handleMessage ====" + msg.what);
        switch (msg.what) {
            case DroidLogicTvUtils.SESSION_DO_RELEASE:
                doRelease();
                break;
            default:
                break;
        }
        return false;
    }

    public void doRelease() {
        mHardware.setSurface(null, null);
        mTvInputManager.releaseTvInputHardware(mDeviceId, mHardware);
        releaseThread();
    }

    @Override
    public void onRelease() {
        mSessionHandler.obtainMessage(DroidLogicTvUtils.SESSION_DO_RELEASE).sendToTarget();
    }

在initThread 函数中,构造完HandlerThread 后会调用start,初始化Looper。接着通过getLooper 创建一个Handler进行通信使用。

Android TV 中要求有些操作时间不能过长,例如onRelease,通过这样的操作就成功避免了

至此,HandlerThread 的源码基本分析完成。总结:

  • HandlerThread 是一个拥有自己Looper 的Thread;
  • HandlerThread 可以通过Looper创建Handler,用以msg 的发送和处理;
  • HandlerThread 是个Thread,执行时需要先调用start();
  • quit 分safe 和非safe 模式;

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

私房菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值