Android HandlerThread的使用

1.简述

HandlerThread继承自Thread的特殊线程,内置有Looper和MessageQueue。 区别于Handler,Handler是消息处理器,用于发送和处理Message和Runable。 HandlerThread是为特定场景(持续性后台任务)优化的线程实现。

2.HandlerThread作用

提供了一个独立的后台线程,专门用于处理耗时任务(如文件读写、网络请求)。 有效避免主线程执行耗时操作导致ANR(Application Not Responding)。 和Handler详细区别:

  • 1.Handler 本质是消息处理,非线程,需要显式指定Looper(如:Looper.getMainLooper() ), 比较适合,子线程要更新主线程UI,定时任务(postDelayed())。 生命周期是需要手动管理,如在Activity销毁时移除消息!! 注意: Handler使用非静态内部类时,可能隐式持有Activity引用,导致内存泄漏 解决上:使用静态内部类+弱引用【一个对象只有弱引用指向它,那么这个对象会在下一次GC时被回收,不论当前内存是否 充足】
  • 2.HandlerThread 继承Thread,带有Looper的后台线程,启动后自动创建。 它启动后持续的后台任务(对于需要持续后台操作是优势),并且避免了多线程并发问题。 生命周期需要调用quite() 或 quiteSafely() 终止Looper。

3.实例使用

先看一下Handler的使用:

// 在主线程创建 Handler(默认绑定主线程 Looper)--如果需要绑定其它线程,要指明
Handler mainHandler = new Handler(Looper.getMainLooper()) {
    @Override
    public void handleMessage(Message msg) {
        // 在主线程处理消息(更新 UI)
        textView.setText("收到消息: " + msg.obj);
    }
};

// 在子线程中发送消息到主线程
new Thread(() -> {
    Message msg = Message.obtain();
    msg.obj = "来自子线程的数据";
    mainHandler.sendMessage(msg);
}).start();

再对比看一下HandlerThread(独立的后台线程):

// 创建并启动 HandlerThread
HandlerThread handlerThread = new HandlerThread("BackgroundThread");
handlerThread.start();

// 获取 HandlerThread 的 Looper,并创建 Handler
Handler backgroundHandler = new Handler(handlerThread.getLooper()) {
    @Override
    public void handleMessage(Message msg) {
        // 在后台线程处理消息(执行耗时任务)
        doHeavyWork();
    }
};

// 发送消息到后台线程---注意这个是发送消息后,在新建立的HandlerThread上下文执行
backgroundHandler.sendEmptyMessage(0);

// 任务结束后终止线程
handlerThread.quitSafely();

4.其它方案

线程池,比如(ExecutorServie),适合多任务并发执行,避免频繁创建线程(暂未使用,并看性能等)