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

Handler.post中变量无法修改,导致工作状态判断始终返回false的解决办法

问题根源

你遇到的问题本质是异步操作的执行顺序问题:handler.post里的网络请求是异步执行的,而函数的return isWorking会在网络请求完成前就执行,所以返回的是初始值false,后续异步操作修改isWorking对返回结果没有任何影响。

另外还要注意:你原来的代码把网络请求放到了主线程(handler.post是往主线程队列加任务),这会导致主线程阻塞,很容易引发ANR(应用无响应),必须放到子线程执行。

解决方案

方法1:使用Kotlin协程(Android开发推荐方案)

把checkWorking改成挂起函数,借助协程等待网络请求完成后再返回结果,代码逻辑更简洁:

// 改成挂起函数,需要依赖kotlinx-coroutines-android库
private suspend fun checkWorking(sharedPreferences: SharedPreferences): Boolean {
    val userId = sharedPreferences.getString("userId", "").toString()
    if (userId.isEmpty()) {
        return false
    }

    // 切换到IO线程执行网络请求
    return withContext(Dispatchers.IO) {
        val field = arrayOfNulls<String>(1)
        field[0] = "user_id"
        val data = arrayOfNulls<String>(1)
        data[0] = userId
        val putData = PutData(
            Database().host + Database().databaseName + "checkWorking.php",
            "POST",
            field,
            data
        )
        var isWorking = false
        if (putData.startPut()) {
            if (putData.onComplete()) {
                val result = putData.result
                // 注意:PHP返回的是"Success"/"Failure",要和后端返回值匹配
                isWorking = result == "Success"
            }
        }
        isWorking
    }
}

调用时需要在协程作用域内(比如Activity/Fragment的lifecycleScope):

lifecycleScope.launch {
    val isWorking = checkWorking(sharedPreferences)
    // 根据状态跳转对应页面
    if (isWorking) {
        // 打开工作中页面
    } else {
        // 打开未工作页面
    }
}

方法2:使用回调接口

如果不想用协程,可以通过回调接口在网络请求完成后获取结果:

第一步:定义回调接口

interface WorkingStatusCallback {
    fun onStatusResult(isWorking: Boolean)
}

第二步:修改checkWorking函数

private fun checkWorking(
    sharedPreferences: SharedPreferences,
    callback: WorkingStatusCallback
) {
    val userId = sharedPreferences.getString("userId", "").toString()
    if (userId.isEmpty()) {
        callback.onStatusResult(false)
        return
    }

    // 在子线程执行网络请求
    Thread {
        val field = arrayOfNulls<String>(1)
        field[0] = "user_id"
        val data = arrayOfNulls<String>(1)
        data[0] = userId
        val putData = PutData(
            Database().host + Database().databaseName + "checkWorking.php",
            "POST",
            field,
            data
        )
        var isWorking = false
        if (putData.startPut()) {
            if (putData.onComplete()) {
                val result = putData.result
                isWorking = result == "Success"
            }
        }
        // 回到主线程处理页面跳转
        Handler(Looper.getMainLooper()).post {
            callback.onStatusResult(isWorking)
        }
    }.start()
}

第三步:调用函数

checkWorking(sharedPreferences, object : WorkingStatusCallback {
    override fun onStatusResult(isWorking: Boolean) {
        if (isWorking) {
            // 打开工作中页面
        } else {
            // 打开未工作页面
        }
    }
})
额外注意事项
  1. 线程问题:网络请求必须放在子线程执行,绝对不能在主线程做耗时操作,否则会引发ANR。
  2. 结果匹配:你的Kotlin代码里原本判断result == "You are working",但PHP返回的是Success或Failure,两者不匹配,必须统一判断逻辑,否则即使请求成功也会得到错误结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 16:15:35