API请求失败时加载指示器未隐藏问题(需用指定ViewModel代码)
解决API请求失败时加载指示器无法隐藏的问题
问题场景
首次调用API获取条目列表时,初始阶段显示加载指示器;数据成功加载时,加载指示器可正常隐藏,但API请求失败时,加载指示器无法隐藏。
问题分析
从提供的代码来看,API请求失败时的错误回调中虽设置了Resource(Status.ERROR, it),但RxJava默认在IO线程执行订阅回调,而LiveData.setValue()必须在主线程调用才能触发UI状态更新,导致错误状态无法传递到UI层,加载指示器因此无法隐藏。
解决方案
通过以下两种方式确保LiveData的状态更新在主线程执行,让UI层能接收错误状态并隐藏加载指示器:
方案1:添加主线程调度器
在API请求的Observable链中加入observeOn(AndroidSchedulers.mainThread()),强制订阅回调在主线程执行:
private fun getIncomingStiDest() { val queries = mapOf( "last_status" to stiDest, "type" to incoming ) getStiDestActionLiveData.value = Resource(Status.LOADING) getDashboardCounterUseCase.execute(queries) .asPageLoadEventSource() .observeOn(AndroidSchedulers.mainThread()) // 切换到主线程执行回调 .subscribe({ getStiDestActionLiveData.value = Resource(Status.SUCCESS, it) }, { getStiDestActionLiveData.value = Resource(Status.ERROR, null, it.message) }) .also { disposables.add(it) } // 用CompositeDisposable管理订阅,避免内存泄漏 }
方案2:使用postValue()替代setValue()
postValue()会自动切换到主线程执行状态更新,无需额外调度器:
private fun getIncomingStiDest() { val queries = mapOf( "last_status" to stiDest, "type" to incoming ) getStiDestActionLiveData.postValue(Resource(Status.LOADING)) getDashboardCounterUseCase.execute(queries).asPageLoadEventSource().subscribe({ getStiDestActionLiveData.postValue(Resource(Status.SUCCESS, it)) }, { getStiDestActionLiveData.postValue(Resource(Status.ERROR, null, it.message)) }).also { disposables.add(it) } }
额外提示
- 确保UI层能正确识别
Resource类的Status.ERROR状态,执行隐藏加载指示器的逻辑。 - 建议在ViewModel中维护
CompositeDisposable,在ViewModel销毁时调用disposables.clear()清理所有订阅,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Rizki Ramdhani
相关产品推荐
相关产品推荐

