@Keep
@Composable
@InternalCoroutinesApi
@ExperimentalCoroutinesApi
fun SetupNavigationHost(
navController: NavHostController,
) {
NavHost(
navController = navController,
startDestination = Screen.MainScreen.route,
)
{
composable(
Screen.MainScreen.route,
deepLinks = listOf(navDeepLink { uriPattern = Screen.MainScreen.deepLinkRoute })
) {
HomeScreen(
navController = navController
)
}
composable(
Screen.ShowTimeslotDetails.route,
arguments = listOf(
navArgument("id") {}
)
) { backStackEntry ->
backStackEntry.arguments?.getString("id")
?.let {
val viewModel: TimeslotViewModel = assistedViewModel {
TimeslotViewModel.provideFactory(timeslotViewModelFactory(), it.toInt())
}
ShowTimeslotDetails(
timeslotId = it.toInt(),
viewModel = viewModel,
navController = navController
)
}
}
}
}
Ошибка возникает в этой строке:
assistedViewModel {
TimeslotViewModel.provideFactory(timeslotViewModelFactory(), it.toInt())
}
видМодель:
@Module
@InstallIn(ActivityRetainedComponent::class)
interface AssistedInjectModule
class TimeslotViewModel @AssistedInject constructor(
@Assisted private val timeslotId: Int,
) : ViewModel() {
@AssistedFactory
interface Factory {
fun create(timeslotId: Int): TimeslotViewModel
}
@Suppress("UNCHECKED_CAST")
companion object {
fun provideFactory(factory: Factory, id: Int): ViewModelProvider.Factory {
return object : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return factory.create(id) as T
}
}
}
}
}
Основная деятельность
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
@EntryPoint
@InstallIn(ActivityComponent::class)
interface ViewModelFactoryProvider {
fun timeslotViewModelFactory(): TimeslotViewModel.Factory
}
...
}
Ошибка:
FATAL EXCEPTION: main
Process: com.example.versions10, PID: 20465
java.lang.ArrayIndexOutOfBoundsException: length=109; index=-1
at java.util.ArrayList.remove(ArrayList.java:506)
at androidx.compose.runtime.Stack.pop(Stack.kt:26)
at androidx.compose.runtime.ComposerImpl.exitGroup(Composer.kt:2246)
at androidx.compose.runtime.ComposerImpl.end(Composer.kt:2408)
at androidx.compose.runtime.ComposerImpl.endGroup(Composer.kt:1578)
at androidx.compose.runtime.ComposerImpl.endRoot(Composer.kt:1462)
at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:3367)
at androidx.compose.runtime.ComposerImpl.recompose$runtime_release(Composer.kt:3307)
at androidx.compose.runtime.CompositionImpl.recompose(Composition.kt:772)
at androidx.compose.runtime.Recomposer.performRecompose(Recomposer.kt:1047)
at androidx.compose.runtime.Recomposer.access$performRecompose(Recomposer.kt:124)
at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:541)
at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:510)
at androidx.compose.ui.platform.AndroidUiFrameClock$withFrameNanos$2$callback$1.doFrame(AndroidUiFrameClock.android.kt:34)
at androidx.compose.ui.platform.AndroidUiDispatcher.performFrameDispatch(AndroidUiDispatcher.android.kt:109)
at androidx.compose.ui.platform.AndroidUiDispatcher.access$performFrameDispatch(AndroidUiDispatcher.android.kt:41)
at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.doFrame(AndroidUiDispatcher.android.kt:69)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1299)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1309)
at android.view.Choreographer.doCallbacks(Choreographer.java:923)
at android.view.Choreographer.doFrame(Choreographer.java:847)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1283)
at android.os.Handler.handleCallback(Handler.java:942)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8741)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)
Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: \[androidx.compose.runtime.PausableMonotonicFrameClock@cb194e5, androidx.compose.ui.platform.MotionDurationScaleImpl@1185bba, StandaloneCoroutine{Cancelling}@f2dea6b, AndroidUiDispatcher@dbb99c8\]
Эта ошибка возникает после выполнения этих обновлений (до обновления работало нормально):
LaunchedEffect(it.toInt()) {
val viewModel: TimeslotViewModel = assistedViewModel {
TimeslotViewModel.provideFactory(timeslotViewModelFactory(), it.toInt())
}
// Use the viewModel here
}
Это должно гарантировать, что ViewModel создается за пределами компонуемой функции, что должно избежать ошибки времени выполнения Compose.
Ошибка исправлена в Android Studio 2022.3.1 Beta 1.
Спасибо, я пытался сделать, как вы сказали, но я получаю эту ошибку на assistViewModel: Composable вызовы могут происходить только из контекста Composable функции. Я делаю что-то неправильно? новый код:
composable(... ){ backStackEntry -> backStackEntry.arguments?.getString("id")?.let { var viewModel: TimeslotViewModel LaunchedEffect(it.toInt()) { viewModel = assistedViewModel { TimeslotViewModel.provideFactory( timeslotViewModelFactory(), it.toInt()) } } ShowTimeslotDetails( viewModel ) } }