导航至使用@HiltViewModel的Composable页面时应用崩溃问题求助
看起来你遇到的是Hilt依赖注入的基础配置疏漏问题,从错误日志里的核心提示IllegalStateException: Hilt Activity must be attached to an @HiltAndroidApp Application就能直接定位到关键——你的App没有正确配置Hilt的全局入口,导致加载带@HiltViewModel的页面时,依赖注入容器无法初始化。
你可以按照下面的步骤逐一排查修复:
1. 确保存在标记了@HiltAndroidApp的Application类
Hilt需要一个全局的Application类作为依赖注入的入口,你需要创建(或确认已有)一个继承自Application的类,并添加@HiltAndroidApp注解:
@HiltAndroidApp class IntroApp : Application() { // 这里可以添加App级别的初始化逻辑,不需要额外写其他Hilt相关代码 }
这个注解会让Hilt自动生成依赖注入容器的核心代码,是所有Hilt注入的基础。
2. 在Manifest中指定这个Hilt Application
打开你的AndroidManifest.xml,找到<application>标签,必须通过android:name属性指定上面创建的Application类,否则系统会使用默认的Application,无法触发Hilt的初始化:
<application android:name=".IntroApp" <!-- 这里替换成你的Hilt Application类的全路径或相对路径 --> android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.IntroApp"> <!-- 你的Activity声明等内容 --> <activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application>
注意:如果你的Application类不在根包下,要写完整的包名路径,比如com.introapp.IntroApp。
3. 确保宿主Activity标记了@AndroidEntryPoint
你的MainActivity是承载NavHost的容器Activity,必须添加@AndroidEntryPoint注解,这样Hilt才能为这个Activity绑定依赖容器,进而支持Composable中hiltViewModel()的调用:
@AndroidEntryPoint class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { IntroAppTheme { val navController = rememberNavController() NavHost( navController = navController, startDestination = Screen.Splash.route ) { // 你的导航路由定义 composable(Screen.Splash.route) { SplashScreen { navController.navigate(Screen.Onboarding.route) { popUpTo(Screen.Splash.route) { inclusive = true } } } } composable(Screen.Onboarding.route) { OnboardingScreen(navController) } composable(Screen.Profile.route) { ProfileScreen(navController) } } } } } }
只有标记了这个注解的Activity,Hilt才能在其生命周期内创建对应的Component,让hiltViewModel()可以正确获取到@HiltViewModel标记的ViewModel实例。
4. 验证ProfileViewModel的注解正确性
最后确认你的ProfileViewModel确实正确使用了Hilt的ViewModel注解,构造函数需要用@Inject标记(如果有依赖需要注入的话):
@HiltViewModel class ProfileViewModel @Inject constructor( // 这里可以添加你需要注入的依赖,比如Repository等 ) : ViewModel() { // ViewModel的业务逻辑 }
为什么引导页没问题,到Profile页才崩溃?
因为引导页的ViewModel可能没有使用@HiltViewModel(或者你是手动创建的),不需要Hilt的容器支持;而Profile页调用hiltViewModel()时,会尝试从宿主Activity的Hilt Component中获取实例,但此时因为Application没配置,Activity的Hilt Component无法创建,所以直接抛出异常。
最后建议你执行Clean Project -> Rebuild Project,或者点击Android Studio的File -> Invalidate Caches... -> Invalidate and Restart,清除可能存在的编译缓存,确保所有配置生效。
内容来源于stack exchange

