Я знаю, что рекомендуется использовать ViewModel с нашей Activity, чтобы мы могли использовать viewModelScope
. Поскольку ViewModel переживает действие, нам не нужно отменять наши задания в activity.onDestroy()
.
Однако иногда у вас есть простое действие. Например, он может заполнить представление списка установленными отфильтрованными пакетами. Вы можете очень просто создать область действия, используя делегата, и отменить задания в 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, который сам по себе является моделью представления.
Приведенный выше код облегчает сбор данных в фоновом режиме. Проблема в том, что при повороте экрана или во время других изменений конфигурации сопрограмма отменяется и перезапускается. Есть ли чистый рецепт для поддержания CoroutineScope в действии путем изменения конфигурации для очень простого действия, подобного этому?
onRetainNonConfigurationInstance()
не рекомендуется. Я полагаю, что мы могли бы поместить его во Fragment и использовать retainInstance = true
, но введение слоя Fragment в такое простое действие также кажется излишним.
Может быть, есть способ создать пустую реализацию ViewModel просто так, чтобы мы могли одолжить свою сферу?