You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级后assistedViewModel触发ArrayIndexOutOfBoundsException异常

问题

完成以下版本升级后(此前运行正常),使用assistedViewModel创建TimeslotViewModel时触发ArrayIndexOutOfBoundsException异常:

  • kotlinCompilerExtensionVersion = "1.4.3"
  • jvmTarget设为"17",sourceCompatibility与targetCompatibility设为Java 17
  • kotlin-android插件版本为1.8.10
  • com.android.application插件版本为8.1.0-alpha11

报错位置代码

assistedViewModel {
   TimeslotViewModel.provideFactory(timeslotViewModelFactory(), it.toInt())
}

相关代码

导航代码

@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
                    )
                }
        }


    }
}

ViewModel代码

@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
                }
            }
        }
    }

}

MainActivity代码

@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]
解决方案

1. 降级AGP到稳定版

当前使用的com.android.application是8.1.0-alpha11预览版,这类版本存在兼容性风险,建议降级到最新稳定版(如8.0.2),同时确保kotlin-android插件版本与AGP版本匹配。

2. 调整Composable内ViewModel创建逻辑

原代码在nullable链式调用的let块内创建ViewModel,可能导致Compose重组时出现栈异常。重构代码结构,显式处理id为空的情况:

composable(
    Screen.ShowTimeslotDetails.route,
    arguments = listOf(
        navArgument("id") {}
    )
) { backStackEntry ->
    val id = backStackEntry.arguments?.getString("id")?.toIntOrNull()
    if (id != null) {
        val viewModel: TimeslotViewModel = assistedViewModel {
            TimeslotViewModel.provideFactory(timeslotViewModelFactory(), id)
        }
        ShowTimeslotDetails(
            timeslotId = id,
            viewModel = viewModel,
            navController = navController
        )
    } else {
        // 处理id无效场景,例如返回上一页
        LaunchedEffect(Unit) {
            navController.popBackStack()
        }
    }
}

3. 同步依赖版本

确保Hilt、Compose相关依赖版本与kotlin、AGP版本兼容:

  • 升级Hilt到最新稳定版(如2.48)
  • 确保Compose runtime、ui等依赖版本与kotlinCompilerExtensionVersion匹配(1.4.x对应Compose BOM 2023.03.00)

内容的提问来源于stack exchange,提问作者Sepidehye Fanavari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 04:57:01