You need to enable JavaScript to run this app. 如何在使用协程的ViewModel中正确实现Result.Success与Result.Error
优惠活动
大模型
产品
解决方案
定价
更多

如何在使用协程的ViewModel中正确实现Result.Success与Result.Error

改造步骤

1. 改造 GiphyTaskRepository 层

首先在仓库层对请求结果和异常做统一包装,直接返回你定义的Result密封类:

class GiphyTaskRepository
@Inject
constructor(private val giphyTaskApiService: GiphyTaskApiService)
{
    suspend fun getGifsFromText(apikey:String,text:String,limit:Int): Result {
        return try {
            val response = giphyTaskApiService.getGifsFromText(apikey,text,limit)
            when {
                // 请求成功且响应体不为空
                response.isSuccessful && response.body() != null -> {
                    Result.Success(response.body()!!.data)
                }
                // 请求成功但响应体为空/请求失败
                else -> {
                    Result.Error(Exception(response.message() ?: "请求失败,响应内容为空"))
                }
            }
        } catch (e: Exception) {
            // 捕获网络异常、超时、序列化失败等请求过程中抛出的异常
            Result.Error(e)
        }
    }
}

2. 改造 GiphyTaskViewModel 层

调整LiveData的类型为Result,直接接收仓库返回的密封类结果:

@HiltViewModel
class GiphyTaskViewModel
@Inject
constructor(private val giphyTaskRepository: GiphyTaskRepository):ViewModel()
{
    // 调整LiveData类型为Result,包含成功/失败两种状态
    var giphyresponse = MutableLiveData<Result>()

    fun getGifsFromText(apikey:String,text:String,limit:Int)= viewModelScope.launch {
        val result = giphyTaskRepository.getGifsFromText(apikey,text,limit)
        giphyresponse.postValue(result)
    }
}

3. 页面层使用示例

在Activity/Fragment观察LiveData时,直接判断密封类类型即可处理对应逻辑:

viewModel.giphyresponse.observe(this) { result ->
    when(result) {
        is Result.Success -> {
            val data = result.data as List<DataItem>
            // 渲染列表逻辑
        }
        is Result.Error -> {
            val errorMsg = result.exception.message ?: "未知错误"
            // 弹窗/toast提示错误逻辑
        }
    }
}

可选优化:给Result加上泛型支持

你当前定义的Result携带的成功数据是Any类型,使用时需要强转,建议改成泛型实现提升类型安全性:

// 泛型版Result密封类
sealed class Result<out T> {
    data class Success<out T>(val data: T) : Result<T>()
    data class Error(val exception: Exception) : Result<Nothing>()
}

对应调整仓库层返回值类型:

suspend fun getGifsFromText(apikey:String,text:String,limit:Int): Result<List<DataItem>> {
    // 内部逻辑不变,返回时Success携带List<DataItem>即可
}

对应调整ViewModel的LiveData类型:

var giphyresponse = MutableLiveData<Result<List<DataItem>>>()

此时页面层使用时不需要再强转数据类型:

is Result.Success -> {
    val data = result.data // 自动识别为List<DataItem>
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 06:06:03