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

使用同步块等待Task结果致应用冻结,该如何解决?

嗨,这个问题我之前也踩过坑,核心问题出在主线程阻塞和回调线程的冲突上,咱们慢慢捋清楚:

为什么你的代码会导致应用冻结?
  • 首先,你大概率是在Android主线程里调用了synchronized(lock){ lock.wait(); }——主线程一旦进入等待状态,就会彻底卡住,没法处理任何UI事件、回调逻辑,整个应用自然就失去响应了。
  • 其次,Google Play Services的Task默认情况下,onSuccess()这类回调是在主线程执行的。这就形成了死锁:主线程等着被notifyAll()唤醒,但负责执行唤醒逻辑的onSuccess()根本没机会运行,因为主线程已经挂起了,循环往复,应用就彻底冻结了。
正确处理Task完成的几种方式

1. 优先用Task的链式回调(非阻塞,推荐)

这是Google设计Task的初衷,完全不用阻塞线程,直接通过回调链处理结果,代码更清晰也更安全:

yourTask.addOnSuccessListener(result -> {
    // 在这里处理任务成功的结果,比如更新UI、传递数据
    processSuccessResult(result);
}).addOnFailureListener(exception -> {
    // 处理任务失败的情况
    handleFailure(exception);
}).addOnCompleteListener(task -> {
    // 不管成功失败都会执行,适合做收尾工作,比如关闭加载弹窗
    finishLoading();
});

这种方式下,所有回调会在合适的线程执行(默认主线程,也可以通过addOnSuccessListener(Executor, OnSuccessListener)指定后台线程),完全不会阻塞主线程,自然不会出现冻结问题。

2. 必须同步获取结果?放到后台线程!

如果你确实需要同步拿到Task的结果(比如在某个后台逻辑里),绝对不能在主线程操作,可以用Tasks.await()方法,但一定要放在后台线程中执行:

// 示例:用Thread开启后台线程
new Thread(() -> {
    try {
        // 阻塞当前后台线程,直到Task完成
        ResultType result = Tasks.await(yourTask);
        // 拿到结果后,回到主线程处理UI(如果需要)
        runOnUiThread(() -> updateUIWithResult(result));
    } catch (ExecutionException | InterruptedException e) {
        // 处理异常情况,比如任务失败、线程被中断
        e.printStackTrace();
    }
}).start();

⚠️ 注意:Tasks.await()会阻塞调用它的线程,所以一定要确保这个线程不是主线程,否则还是会导致应用冻结。

3. Kotlin项目?用协程更优雅

如果是Kotlin开发,可以借助kotlinx-coroutines-play-services库提供的扩展函数,用协程以同步风格处理异步任务,同时避免阻塞主线程:

// 比如在Activity/Fragment的lifecycleScope中执行
lifecycleScope.launch(Dispatchers.IO) {
    try {
        // 协程挂起,不会阻塞线程
        val result = yourTask.await()
        // 回到主线程处理UI
        withContext(Dispatchers.Main) {
            updateUI(result)
        }
    } catch (e: Exception) {
        // 处理异常
        showError(e.message)
    }
}

总结一下:永远不要在Android主线程使用wait()/notify()这类阻塞方法,Task的设计核心就是异步回调,优先用链式回调处理;如果一定要同步获取结果,务必放到后台线程执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:36:45