ArrayIndexOutOfBoundsException в AssistViewModel после обновления

@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\]

Эта ошибка возникает после выполнения этих обновлений (до обновления работало нормально):

  • kotlinCompilerExtensionVersion = "1.4.3"
  • jvmTarget = "17"
  • исходная совместимость = JavaVersion.VERSION_17
  • целевая совместимость = JavaVersion.VERSION_17
  • id("org.jetbrains.kotlin.android") версии "1.8.10" применить false
  • id("com.android.application") версии "8.1.0-alpha11" применить false исходный код здесь: https://github.com/CsharpGamer/Update10
0
0
63
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

LaunchedEffect(it.toInt()) {
    val viewModel: TimeslotViewModel = assistedViewModel {
        TimeslotViewModel.provideFactory(timeslotViewModelFactory(), it.toInt())
    }
    // Use the viewModel here
}

Это должно гарантировать, что ViewModel создается за пределами компонуемой функции, что должно избежать ошибки времени выполнения Compose.

Спасибо, я пытался сделать, как вы сказали, но я получаю эту ошибку на 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 ) } }

Sepidehye Fanavari 10.04.2023 14:09
Ответ принят как подходящий

Ошибка исправлена ​​в Android Studio 2022.3.1 Beta 1.

Другие вопросы по теме