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

Android中onResume启动的异步任务未完成时如何处理依赖它的按钮点击

实现方案

以下两种方案均适配你的需求,可根据项目技术栈选择:

方案1:LiveData实现(Java/Kotlin通用,无需修改原有Java异步逻辑)

核心思路是通过LiveData持有异步任务的完成状态,同时用布尔值标记按钮点击状态,任务完成后统一触发逻辑:

  1. 定义状态变量
// 异步任务状态:null=未完成,true=执行成功,false=执行失败
private val asyncTaskState = MutableLiveData<Boolean?>()
// 按钮点击标记
private var isButtonClicked = false
  1. onResume中触发异步任务并更新状态
override fun onResume() {
    super.onResume()
    asyncTaskState.value = null // 每次进入页面重置状态
    // 启动原有异步任务
    YourAsyncTask(object : TaskCallback {
        override fun onSuccess() {
            asyncTaskState.postValue(true)
        }
        override fun onFailure() {
            asyncTaskState.postValue(false)
        }
    }).execute()
}
  1. 按钮点击事件处理
btnAction.setOnClickListener {
    when (asyncTaskState.value) {
        null -> {
            // 任务未完成:展示进度条,标记已点击
            progressBar.visibility = View.VISIBLE
            isButtonClicked = true
        }
        else -> {
            // 任务已完成:直接执行后续逻辑
            doButtonAction(asyncTaskState.value!!)
        }
    }
}
  1. 观察任务状态,任务完成后自动触发等待中的按钮逻辑
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    asyncTaskState.observe(viewLifecycleOwner) { isSuccess ->
        isSuccess ?: return@observe
        // 隐藏进度条
        progressBar.visibility = View.GONE
        // 如果按钮已被点击,执行后续逻辑
        if (isButtonClicked) {
            doButtonAction(isSuccess)
            isButtonClicked = false // 重置标记
        }
    }
}
  1. 封装按钮后续逻辑
private fun doButtonAction(taskSuccess: Boolean) {
    if (taskSuccess) {
        // 异步任务成功时的按钮逻辑
    } else {
        // 异步任务失败时的按钮逻辑,比如错误提示
    }
}

提示:Java项目可完全复用上述逻辑,仅需替换为Java语法即可。

方案2:Kotlin协程实现(纯Kotlin项目更简洁)

核心思路是用Deferred包装异步任务,点击按钮时直接await等待任务完成,无需额外维护点击标记:

  1. 定义变量
private var asyncTaskDeferred: Deferred<Boolean>? = null
private val lifecycleScope by viewLifecycleOwner.lifecycleScope
  1. onResume中用协程封装原有异步任务
override fun onResume() {
    super.onResume()
    asyncTaskDeferred = lifecycleScope.async {
        suspendCoroutine<Boolean> { continuation ->
            // 原有异步任务
            YourAsyncTask(object : TaskCallback {
                override fun onSuccess() = continuation.resume(true)
                override fun onFailure() = continuation.resume(false)
            }).execute()
        }
    }
}
  1. 按钮点击事件处理
btnAction.setOnClickListener {
    lifecycleScope.launch {
        progressBar.visibility = View.VISIBLE
        // 等待异步任务完成,未完成时自动挂起,不会阻塞主线程
        val taskSuccess = asyncTaskDeferred?.await() ?: false
        progressBar.visibility = View.GONE
        // 直接执行后续逻辑
        doButtonAction(taskSuccess)
    }
}

注意事项

  • 两种方案均绑定Fragment生命周期,页面销毁时自动取消观察/协程任务,不会产生内存泄漏
  • 若需要支持任务重试,每次重新触发异步任务时重置对应状态变量即可
  • 若异步任务可取消,可在onPause中添加任务取消逻辑,减少不必要的资源消耗

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 12:36:08