如何在Android中关闭屏幕后的Coroutine(活动/片段)在Android中关闭?

发布于 2025-01-30 03:57:40 字数 1716 浏览 3 评论 0原文

活动类:

class MainActivity : AppCompatActivity() {
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val vm = getViewModel<MyViewModel>()
        vm.invoke()
    }
}

inline fun <reified T : ViewModel> FragmentActivity.getViewModel(): T {
    return ViewModelProvider(this)[T::class.java]
}

我的ViewModel中的代码类看起来如下:

class MyViewModel : ViewModel() {
    private val repository: Repository = Repository()
 
    fun invoke() {
        viewModelScope.launch {
            repository.execute()
        }
    }
}

repository:

private class Repository {
    suspend fun execute() {
        val isSuccess = libraryFunction()
        if (isSuccess) {
            onSuccess()
        }
    }

    suspend fun onSuccess() {
        Log.d("Repo", "onSuccess called")
        delay(1000)
    }
}

来自无法修改的库中的函数:

private val someItems = listOf("1", "2", "3")

suspend fun libraryFunction(): Boolean = coroutineScope {
    someItems.map { item ->
        async {
            processItem(item)
        }
    }.awaitAll()
    true
}
    
suspend fun processItem(item: String) = withContext(Dispatchers.IO) {
    delay(5000) // simulate processing
}

accod>活动 /fragment在执行onsuccess()之前已关闭

onSuccess called

在某些情况下,即使活动/fragment在关闭之前,我也需要执行onsuccess()功能。

不使用globalsCope服务workmanager类而无需使用globalsCope可以做到吗?

Activity class:

class MainActivity : AppCompatActivity() {
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val vm = getViewModel<MyViewModel>()
        vm.invoke()
    }
}

inline fun <reified T : ViewModel> FragmentActivity.getViewModel(): T {
    return ViewModelProvider(this)[T::class.java]
}

The code in my ViewModel class looks like the following:

class MyViewModel : ViewModel() {
    private val repository: Repository = Repository()
 
    fun invoke() {
        viewModelScope.launch {
            repository.execute()
        }
    }
}

Repository:

private class Repository {
    suspend fun execute() {
        val isSuccess = libraryFunction()
        if (isSuccess) {
            onSuccess()
        }
    }

    suspend fun onSuccess() {
        Log.d("Repo", "onSuccess called")
        delay(1000)
    }
}

Function from a library that can't be modified:

private val someItems = listOf("1", "2", "3")

suspend fun libraryFunction(): Boolean = coroutineScope {
    someItems.map { item ->
        async {
            processItem(item)
        }
    }.awaitAll()
    true
}
    
suspend fun processItem(item: String) = withContext(Dispatchers.IO) {
    delay(5000) // simulate processing
}

When Activity/Fragment is closed before onSuccess() is executed the log

onSuccess called

isn't printed in the Logcat.

In some situations I need to execute onSuccess() function even if Activity/Fragment is closed before.

Is it possible to do it without using GlobalScope, Service and WorkManager classes?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

如何视而不见 2025-02-06 03:57:40

您描述的问题与Coroutine范围有关。
您正在使用ViewModelsCope启动Coroutine:

为应用程序中的每个ViewModel定义了一个ViewModelScope。任何
如果该范围在此范围中启动的Coroutine会自动取消
ViewModel已清除。在您拥有的时候,Coroutines在这里很有用
仅当ViewModel处于活动状态时才需要完成。为了
例如,如果要计算一些布局数据,则应范围
到ViewModel的工作,因此,如果清除了ViewModel,则
自动取消工作以避免消耗资源。

https:> https://developer.androd.androd.android.com/topic/topic/libraries/libraries/coroutine/cortinetine-cororinetine-coroutine-coroutine-coroutine-coroutentin-coroutine-coroutetine,# ViewModelScope

您可以使用GlobalsCope或其他其他。
有关Coroutine范围的详细信息,您可以在此处找到:

The issue you described, related to the coroutine scope.
You are using ViewModelScope when launching coroutine:

A ViewModelScope is defined for each ViewModel in your app. Any
coroutine launched in this scope is automatically canceled if the
ViewModel is cleared. Coroutines are useful here for when you have
work that needs to be done only if the ViewModel is active. For
example, if you are computing some data for a layout, you should scope
the work to the ViewModel so that if the ViewModel is cleared, the
work is canceled automatically to avoid consuming resources.

https://developer.android.com/topic/libraries/architecture/coroutines#viewmodelscope

You can use GlobalScope or some other.
Details about coroutine's scope you can find here:
https://www.geeksforgeeks.org/scopes-in-kotlin-coroutines/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文