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 { // 打开未工作页面 } } })
额外注意事项
- 线程问题:网络请求必须放在子线程执行,绝对不能在主线程做耗时操作,否则会引发ANR。
- 结果匹配:你的Kotlin代码里原本判断
result == "You are working",但PHP返回的是Success或Failure,两者不匹配,必须统一判断逻辑,否则即使请求成功也会得到错误结果。
内容的提问来源于stack exchange,提问作者Bendzsike
相关产品推荐
相关产品推荐

