You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中HandlerThread子类重写的run()方法为何无法完整执行?

HandlerThread重写run()看不到结束日志的原因及解决办法

问题根源

你遇到的问题来自两个关键错误:

1. 错误给重写的run()方法添加synchronized修饰符

原HandlerThread的run()方法并没有synchronized修饰,你添加这个关键字后会导致:

  • run()方法执行期间会一直持有当前HandlerThreadTest对象的锁
  • 当主线程调用quitSafely()时,该方法内部会调用getLooper(),而getLooper()包含synchronized (this)同步块,需要获取当前对象的锁
  • 此时HandlerThread的run()卡在Looper.loop()循环,锁被持续持有,主线程的getLooper()会被永久阻塞,quitSafely()无法触发Looper退出,super.run()永远无法返回,自然看不到"Looper end!"日志

2. Handler初始化时机错误

在HandlerThreadTest的构造方法中创建mHandler时,HandlerThread还未启动,此时Handler默认绑定主线程的Looper,而非HandlerThread自身的Looper。这导致你post的Runnable实际在主线程执行,逻辑不符合预期。

修复方案

步骤1:移除run()的synchronized修饰符

恢复run()方法的原有修饰,避免锁阻塞:

@Override
public void run() {
    Log.d(Tag, "Looper start!");
    super.run();
    Log.d(Tag, "Looper end!");
}

步骤2:正确初始化Handler

在onLooperPrepared()方法中初始化mHandler,此时HandlerThread的Looper已创建完成,确保Handler绑定当前线程的Looper:

static class HandlerThreadTest extends android.os.HandlerThread {
    private Handler mHandler;

    public HandlerThreadTest(String name) {
        super(name);
    }

    public HandlerThreadTest(String name, int priority) {
        super(name, priority);
    }

    @Override
    protected void onLooperPrepared() {
        super.onLooperPrepared();
        // 此时Looper已初始化,绑定当前线程的Looper
        mHandler = new Handler(getLooper());
    }

    public Handler getHandler() {
        return mHandler;
    }

    @Override
    public void run() {
        Log.d(Tag, "Looper start!");
        super.run();
        Log.d(Tag, "Looper end!");
    }
}

步骤3:确保HandlerThread启动后再使用

调用test_ThreadHandler前必须先启动线程:

HandlerThreadTest threadTest = new HandlerThreadTest("MyHandlerThread");
threadTest.start();
test_ThreadHandler(threadTest);

验证效果

修复后执行流程:

  1. HandlerThreadTest.start()启动线程,执行run()打印"Looper start!"
  2. super.run()创建Looper并进入循环,onLooperPrepared()初始化绑定当前线程Looper的mHandler
  3. post的Runnable被发送到HandlerThread的消息队列,在该线程执行,打印"handlerThreadTest quit!"并调用quitSafely()
  4. Looper处理完现有消息后退出循环,super.run()返回,打印"Looper end!"
  5. HandlerThread线程正常结束

内容的提问来源于stack exchange,提问作者Jack_Du

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 16:55:19