android - 在 android 中关闭屏幕(Activity/Fragment)后如何保持协程运行?

Activity 类:

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()
        }
    }
}

存储库:

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
}

Activity/Fragment 在执行 onSuccess() 之前关闭时,日志

onSuccess called

没有打印在 Logcat 中。

在某些情况下,即使 Activity/Fragment 之前已关闭,我也需要执行 onSuccess() 函数。

不使用 GlobalScopeServiceWorkManager 类是否可以做到这一点?

回答1

您描述的问题与协程范围有关。您在启动协程时使用 ViewModelScope

为您应用中的每个 ViewModel 定义了一个 ViewModelScope。如果 ViewModel 被清除,则在此范围内启动的任何协程都会自动取消。当您有工作需要在 ViewModel 处于活动状态时完成时,协程在这里很有用。例如,如果您正在为布局计算一些数据,则应将工作范围限定为 ViewModel,以便在清除 ViewModel 时自动取消工作以避免消耗资源。

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

您可以使用 GlobalScope 或其他。您可以在此处找到有关协程范围的详细信息:https://www.geeksforgeeks.org/scopes-in-kotlin-coroutines/

相似文章