首页 > 解决方案 > 取消从 ViewModel 协程作业开始的改造请求

问题描述

我希望我的应用用户能够取消文件上传。

我在 ViewModel 中的协程上传作业看起来像这样

private var uploadImageJob: Job? = null
private val _uploadResult = MutableLiveData<Result<Image>>()
val uploadResult: LiveData<Result<Image>>
    get() = _uploadResult

fun uploadImage(filePath: String, listener: ProgressRequestBody.UploadCallbacks) {
    //...
    uploadImageJob = viewModelScope.launch {
        _uploadResult.value = withContext(Dispatchers.IO) {
            repository.uploadImage(filePart)
        }
    }
}

fun cancelImageUpload() {
    uploadImageJob?.cancel()
}

然后在存储库中,Retrofit 2 请求像这样处理

suspend fun uploadImage(file: MultipartBody.Part): Result<Image> {
    return try {
        val response = webservice.uploadImage(file).awaitResponse()
        if (response.isSuccessful) {
            Result.Success(response.body()!!)
        } else {
            Result.Error(response.message(), null)
        }
    } catch (e: Exception) {
        Result.Error(e.message.orEmpty(), e)
    }
}

cancelImageUpload()它调用时,作业被取消并且异常在存储库中被捕获,但结果不会被分配给uploadResult.value.

任何想法请如何使这项工作?

PS:有一个类似的问题Cancel file upload (retrofit) started from coroutine kotlin android但它建议使用coroutines call adapterwhich is deprecated now。

标签: androidkotlinretrofit2viewmodelcoroutine

解决方案


终于设法通过withContext像这样向上移动一个级别来使其工作

uploadImageJob = viewModelScope.launch {
    withContext(Dispatchers.IO) {
        _uploadResult.postValue(repository.uploadImage(filePart))
    }
}

推荐阅读