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()
功能。
是否可以在不使用 GlobalScope
、Service
和 WorkManager
类的情况下做到这一点?
回答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/