android - 通过配置更改保留 CoroutineScope 的干净方法,无需 ViewModel

标签 android kotlin kotlin-coroutines

我知道建议在我们的 Activity 中使用 ViewModel,这样我们就可以使用它的 viewModelScope。由于 ViewModel 的生命周期比 Activity 的生命周期长,因此我们不必在 activity.onDestroy() 中取消作业。

但是,有时您的 Activity 非常简单。例如,它可以使用已安装的过滤包填充 ListView 。您可以非常简单地使用委托(delegate)创建 Activity 范围,并在 onDestroy() 中取消作业:

class MyActivity(): AppCompatActivity(), CoroutineScope by MainScope() {

    private val listAdapter = MyAdapter()

    override fun onCreate() {
        super.onCreate()
        setContentView(R.layout.my_activity)
        recycler_view.apply {
            layoutManager = LinearLayoutManager(this)
            adapter = listAdapter
        }
        launch {
            val packages = getOrgPackagesWithIcons()
            adapter.apply {
                data = packages
                notifyDataSetChanged()
            }
        }

    }

    override fun onDestroy() {
        super.onDestroy()
        cancel() // CoroutineContext
    }

    private suspend fun getOrgPackagesWithIcons() = withContext(Dispatchers.Default) {
        var toNextYield = 20
        packageManager.getInstalledPackages(0)
            .filter { it.packageName.startsWith("org")
            .take(100)
            .map { 
                     if (--toNextYield == 0) { // Make it cancellable
                         toNextYield = 20
                         yield()
                     }
                     MyPackageData(
                         it.applicationInfo.loadLabel(packageManager).toString(),
                         it.packageName,
                         it.applicationInfo.loadIcon(packageManager)
                     )
                 }
        }

}

对于这样的情况,ViewModel 感觉有点矫枉过正。它只是抽象 PackageManager 的另一层,PackageManager 本身实际上是一个 View 模型。

上面的代码可以很容易地在后台组装数据。问题是,当屏幕旋转时,或者在其他配置更改期间,协程被取消并重新启动。是否有一个干净的方法可以通过像这样的非常简单的 Activity 的配置更改来保持 CoroutineScope 的 Activity ?

onRetainNonConfigurationInstance() 已弃用。我想我们可以将它放在 Fragment 中并使用 retainInstance = true,但是向如此简单的 Activity 引入 Fragment 层也感觉有些过头了。

也许有一种方法可以创建一个空的 ViewModel 实现,这样我们就可以借用它的范围?

最佳答案

For a case like this, ViewModel feels like overkill.

我会反对,但仍然建议这将是 AndroidViewModel 的一个很好的用例.

我相信 Activity 不负责仅仅因为它可以访问 PackageManager 就获取包列表。 Activity 应该只负责显示列表。

使用 AndroidViewModel 可以让您访问 ViewModel 实例中的 ContextviewModelScope

关于android - 通过配置更改保留 CoroutineScope 的干净方法,无需 ViewModel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59881467/

相关文章:

java - 在我的手机游戏中添加图像

android - 协程限制?

android - 谷歌机器学习套件 : Waiting for the text recognition model to be downloaded

Kotlin 协程 : concurrent execution throttling

java - Spring - 如何将组件从另一个模块注入(inject)到 SpringBoot 应用程序中

android - 将 FLAC 或 AMR_WB 中的音频流式传输到 Google Speech API

android - Android 中的 Kotlin - 暂停房间中的功能

kotlin - 多少个协程就太多了?

java - 是否在列表上运行 remove(int index) 方法以删除对象实例调用垃圾收集?

android - 安卓密码提示