Koin VM/навигация на мультиплатформе Kotlin - одноэлементная модель представления не может запустить сопрограмму после pAndroid

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Koin VM/навигация на мультиплатформе Kotlin - одноэлементная модель представления не может запустить сопрограмму после p

Сообщение Anonymous »

Может быть, я делаю что-то не так, но мне это кажется очень странным, мне потребовалось некоторое время, чтобы выяснить причину, но в основном модели ViewModel повреждаются при использовании popBackStack или смахивании влево, виртуальные машины - это синглтоны, созданные с использованием SingleOf(::NameViewModel). если виртуальная машина упоминается на обоих экранах, ответный удар оставляет модель представления неспособной запускать сопрограммы.
Я предполагаю, что это просто потому, что Detailscreen выходит за пределы области видимости с прикрепленной к ней виртуальной машиной, но, поскольку это синглтон, он все равно должен быть доступен в другом месте, все остальные данные участников не повреждены, он просто не может запускать сопрограммы?
Для воспроизведения

Шаги по воспроизведению поведение:
  • Создайте виртуальную машину с помощью SingleOf(::NameViewModel)
  • Добавьте два экрана для перехода от одного к другому
  • создайте виртуальную машину на втором и первом экранах (должна быть одна и та же виртуальная машина), используя

    Код: Выделить всё

    koinViewModel()
    
  • на Android проведите пальцем влево, чтобы вернуться к корневому экрану (или можете использовать popBackStack для кнопки)

Код: Выделить всё

class MyViewModel : ViewModel() {
var name = "Hello"
private var _coroutineRunCount = MutableStateFlow(0)
var coroutineRunCount : StateFlow = _coroutineRunCount

fun runCoroutine() {
println("runCoroutine")
viewModelScope.launch {
println("runCoroutine - Launched *****")
_coroutineRunCount.value += 1
}
}
}

Код: Выделить всё

@Serializable
object Detail

@Serializable
object Home

@Composable
@Preview
fun App() {
startKoin {
modules(
listOf(
module {
singleOf(::MyViewModel)
}
)
)
}

val navController = rememberNavController()

NavHost(
navController = navController,
startDestination = Home,
enterTransition = { EnterTransition.None } ,
exitTransition = { ExitTransition.None }
) {
composable {
HomeScreen(
onDetailClick = {
navController.navigate(Detail)
})
}
composable {
DetailScreen(onBack = {
navController.popBackStack()
})
}

}

}

@Composable
fun HomeScreen(onDetailClick: () -> Unit) {
val viewModel = koinViewModel()
val coroutineRunCount = viewModel.coroutineRunCount.collectAsState()

MaterialTheme {
var showContent by remember { mutableStateOf(false) }
Column(
modifier = Modifier
.background(MaterialTheme.colorScheme.primaryContainer)
.safeContentPadding()
.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text("Home Screen")

Button(onClick = {
onDetailClick()
}) {

Text("Open Detail")
}

Button(onClick = {
viewModel.runCoroutine()
print(viewModel.name)
}) {
Text("Run Coroutine")
}

Text("Coroutine Run Count: ${coroutineRunCount.value}")
}
}
}

@Composable
fun DetailScreen(onBack: () ->  Unit) {
val viewModel = koinViewModel()
val coroutineRunCount = viewModel.coroutineRunCount.collectAsState()

Column(
modifier = Modifier
.background(MaterialTheme.colorScheme.primaryContainer)
.safeContentPadding()
.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text("Detail Screen")

Button(
onClick = {
onBack()
}) {
Text("Backup to home")
}

Button(onClick = {
viewModel.runCoroutine()
print(viewModel.name)
}) {
Text("Run Coroutine")
}

Text("Coroutine Run Count: ${coroutineRunCount.value}")
}
}
В приведенном выше примере перед нажатием кнопки запуска сопрограмма увеличивает счетчик, после открытия детали и отказа она не может увеличить счетчик.
Я создал ошибку в репозитории Koin с полным примером кода, но ответа пока нет, поэтому решил попробовать здесь https://github.com/InsertKoinIO/koin/issues/2310
(проверено как на iOS, так и на Droid, одинаково для обоих платформы

Подробнее здесь: https://stackoverflow.com/questions/798 ... ing-unable
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»