android - 取消从 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 adapter
which is deprecated now。
解决方案
终于设法通过withContext
像这样向上移动一个级别来使其工作
uploadImageJob = viewModelScope.launch {
withContext(Dispatchers.IO) {
_uploadResult.postValue(repository.uploadImage(filePart))
}
}
推荐阅读
- php - 无法使用 composer (version 2.1.4) 创建 laravel 项目
- azure-devops - Azure Dev Ops:如何在工作项模板上设置布尔项的默认值
- postgresql - 粘合 PostgreSQL 连接:“无法找到合适的安全组”
- icons - 使用css创建图标栏
- pdf - pdf如何批量列出带有注释的pdf?qpdf? pdf信息?
- ios - 如何使用头文件定义 obj c 目标,以便其他目标可以在 SPM 中实现它?(错误:产品“Foo”中引用的目标“Foo”为空)
- java - 无限循环真的在java中无限循环吗?
- rust - 如何定义 AccountId32 常量?
- html - 按钮焦点上的 CSS 自定义轮廓
- c# - 为 Identity Server 中的 SSO 指定 response_type=token