在协程内部,借助“kotlinx-coroutines-play-services”库中的await()函数,我使用了类似的方法:
suspend fun uploadFile(uri: Uri) = withContext(IO) {
Firebase.storage.reference.child("example").putFile(uri).await()
}
问题是当当前协程的作业被取消时,该任务不会随之取消,而是继续执行。取消作业后,我需要所有嵌套任务自动停止。有没有办法可以做到这一点?
最佳答案
如果我对您的理解正确,那么您的repository
就属于应用程序范围,因此您的应用程序中只有一个实例。
假设您从repository
调用ViewModel
函数。您可以使用viewModelScope
从具有生命周期意识的协程调用它,并且在viewModel
销毁后将停止。
它可能看起来像这样:
fun uploadFile(uri: Uri) = viewModelScope.launch(Dispatchers.IO) {
repo.uploadFile(uri)
}
现在repository
函数看起来像这样:suspend fun uploadFile(uri: Uri) {
Firebase.storage.reference.child("example").putFile(uri).await()
}
如果您从activity
或fragment
而非viewModel
调用它,则可以编写:lifecycleScope.launch(Dispatchers.IO){
repo.uploadFile(uri)
}
如果您有类似repository
或其他的嵌套调用,例如UseCase
,则只需要在途中的每个函数中添加suspend关键字。编辑:
您可以取消
coroutine
,但是很遗憾,您不能取消firebase
请求。因此,当您取消coroutine
且文件不应该远程保存时,您要处理这种情况。一种简单的方法是使用onDetach
或其他一些方式来处理它(即fragment
或activity
)。您可以使用的一种技巧是将代码放入try
块中的存储库中,并添加finally
块。取消coroutine
时,它将运行,您可以在其中检查文件是否已保存,如果已保存,则将其删除。suspend fun uploadFile(uri: Uri) {
try {
Firebase.storage.reference.child("example").putFile(uri).await()
} finally {
// here handle canceled coroutine
}
}
您可以阅读有关它的更多信息here。
关于android - 将Firebase与Kotlin协同程序一起使用:取消作业时不会取消任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64195870/