将Firebase与Kotlin协同程序一起使用:取消作业时不会取消任务 [英] Using Firebase with Kotlin coroutines: Task is not canceled when job is canceled

查看:71
本文介绍了将Firebase与Kotlin协同程序一起使用:取消作业时不会取消任务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在协程内部,借助"kotlinx-coroutines-play-services"中的await()函数,库,我使用类似这样的东西:

Inside a coroutine, with the help of await() function from "kotlinx-coroutines-play-services" library, i use something like this:

suspend fun uploadFile(uri: Uri) = withContext(IO) {
    Firebase.storage.reference.child("example").putFile(uri).await()
}

问题是当取消当前协程的Job时,该任务不会随之取消,而是继续执行.

The problem is when the Job of the current coroutine is canceled, this task is not canceled with it and keeps executing.

我需要所有嵌套任务才能在作业取消时自动停止.有什么办法可以做到这一点?

I need all nested tasks to auto-stop when the job is canceled. Is there a way I can achieve this?

推荐答案

如果我对您的理解正确,那么您的repository属于应用程序范围,因此在您的应用程序中只有一个实例.
假设您从ViewModel调用repository函数.您可以使用viewModelScope从具有生命周期意识的协程调用它,并且当viewModel被销毁时它将停止. 看起来可能像这样:

If I understand you correctly you have your repository that is is application scoped, so that there is one instance of it in your app.
Let's assume you call your repository function from the ViewModel. You can use viewModelScope to call it from a coroutine that will be lifecycle aware and it will be stopped when the viewModel is destroyed.
It could look like this:

fun uploadFile(uri: Uri) = viewModelScope.launch(Dispatchers.IO) {
    repo.uploadFile(uri)
}

repository函数现在看起来像这样:

And the repository function could now look like this:

suspend fun uploadFile(uri: Uri) {
    Firebase.storage.reference.child("example").putFile(uri).await()
}

如果从activityfragment而不是viewModel调用它,则可以写:

If you call it from the activity or the fragment not viewModel you can instead write:

lifecycleScope.launch(Dispatchers.IO){
    repo.uploadFile(uri)
}

如果您有嵌套调用,如repositoryUseCase之类的调用,则只需要在途中的每个函数中添加suspend关键字即可.

If you have nested calls like the repository is called by like a UseCase or sth else, you just need to add suspend keyword in every function on the way.


您可以取消coroutine,但是很遗憾,您不能取消firebase请求.因此,当您取消coroutine且文件不应远程保存时,您要处理这种情况.一种简单的方法是在onDetach中处理它,或者在fragmentactivity中进行其他处理.您可以使用的一种技巧是将代码放在存储库中的try块中,然后添加finally块.当取消coroutine时它将运行,您可以在其中检查文件是否已保存,如果已保存,则将其删除.


You can cancel the coroutine, but unfortunately you cannot cancel the firebase request. So you want to handle the situation when you cancel the coroutine and the file should not be saved remotely. One simple way is to handle it in onDetach or sth else in fragment or activity. One trick you could use is to put you code in the repository in try block and add finally block. It will be run when the coroutine is canceled and there you could check whether file is saved and if so, delete it.

suspend fun uploadFile(uri: Uri) {
    try {
        Firebase.storage.reference.child("example").putFile(uri).await()
    } finally {
        // here handle canceled coroutine
    }
}

您可以在此处了解更多信息.

You can read more about it here.

这篇关于将Firebase与Kotlin协同程序一起使用:取消作业时不会取消任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆