【问题标题】:Getting error from creating a Hilt viewModel创建 Hilt viewModel 时出错
【发布时间】:2021-04-29 14:36:21
【问题描述】:

我试图将一个简单的 viewModel 交给一个可组合的,并在每次出现此错误时都会收到此错误,但我不知道这意味着什么:

java.lang.IllegalStateException: Given component holder class com.example.app.MainActivity does not implement interface dagger.hilt.internal.GeneratedComponent or interface dagger.hilt.internal.GeneratedComponentManager

我的摇篮:

    implementation("androidx.hilt:hilt-navigation:1.0.0-beta01")
    implementation("androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03")

我创建了一个BaseApplication 文件

import android.app.Application
import dagger.hilt.android.HiltAndroidApp

@HiltAndroidApp
class BaseApplication: Application()

并将其设置在 Manifest 中。

我创建了一个AppModule 文件:

import android.content.Context
import com.veloce.montageservice.BaseApplication
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
object AppModule {

    @Singleton
    @Provides
    fun provideApplication(@ApplicationContext app: Context): BaseApplication {
        return app as BaseApplication
    }
}

然后在我的MainActivity 中设置@HiltAndroidApp 并创建一个viewModel,如下所示:

@HiltViewModel
class TaskViewModel: ViewModel() {

//code

}

viewModel 在我的导航中被调用 MainActivity:

 val navController = rememberNavController()
 NavHost(
     navController = navController,
     startDestination = Screens.LoginScreen.route
 ) {
 composable(Screens.ActiveMontageScreen.route) { navBackStackEntry ->
     activeTask?.let {
         val factory =
             HiltViewModelFactory(LocalContext.current, navBackStackEntry)
         val viewModel: TaskViewModel = viewModel("taskViewModel", factory)
         ActiveMontageScreen(
             viewModel = viewModel,
             task = it,
             navigation = navController,
             context = LocalContext.current
         ) {
             removeActiveTask()
         }
     }
 }
}

我真的看不出有什么问题,但是我对 Hilt 和 Android 开发非常缺乏经验。 有谁知道问题出在哪里?

【问题讨论】:

    标签: android kotlin android-jetpack-compose dagger-hilt


    【解决方案1】:

    据我所知,很少有东西放错了地方,导致了这样的错误。

    例如:

    1. 如果您需要viewmodel 中的上下文,则您没有在class TaskViewModel(context: Context) 中注入上下文,那么您可以使用AndroidViewModel

    2. 你正在AppModule 中创建BaseApplication,但你没有使用它(可能在其他地方使用)。

    您可以通过以下步骤创建这样的视图模型:

    1. 创建BaseApplication 并在清单中注册,您已经完成了。

    2. 如下创建AndroidViewModel

      @HiltViewModel
      class TaskViewModel @Inject constructor(
       application: BaseApplication
      ) : AndroidViewModel(application) {
      
       fun test() {
           getApplication<BaseApplication>().getString(R.string.app_name)
       }
      
      }  
      

    这里注意@Inject constructor 的使用,它将从AppModule 获取BaseApplication 类。

    1. 在您的MainActivity 中初始化viewmodel,如下所示:

      @AndroidEntryPoint
      class MainActivity : AppCompatActivity() {
      
       private val viewModel: TaskViewModel by viewModels()
      
       override fun onCreate(savedInstanceState: Bundle?) {
           super.onCreate(savedInstanceState)
           setContentView(R.layout.activity_main)
      
           viewModel.test()
       }
      
      }
      

    如果您无法解决任何与刀柄相关的问题,请确保您在 build.gradle 中有这些依赖项

    //Dagger - Hilt
        implementation "com.google.dagger:hilt-android:2.33-beta"
        kapt "com.google.dagger:hilt-android-compiler:2.33-beta"
        implementation "androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03"
        kapt "androidx.hilt:hilt-compiler:1.0.0-beta01"
    

    【讨论】:

    • 在我点击发布按钮 30 秒后,上下文没有意义对我来说很清楚。 :-) 我已经把它拿出来并尝试了你的建议,但不幸的是没有任何改变,同样的错误
    • 我已经看到MainActivity 中的注释是错误的,因此对其进行了更改。我收到了一个新错误java.lang.RuntimeException: Cannot create an instance of class com.example.app.ui.view_models.TaskViewModel
    • @ChrisPi 你在TaskViewModel 中使用了@Inject constructor 吗?如果没有,那么你应该。另外,您是否尝试过我给您的在MainActivity 中初始化视图模型的方法?
    • 是的,我进行了更改。我现在正在尝试实施 kapt
    • @ChrisPi 太好了。我希望你能解决它。
    【解决方案2】:

    所以对于你的视图模型,你需要根据你的版本依赖添加注释 @Inject 或 @ViewModelInject 并像这样创建它

    class TaskViewModel @Inject constructor(context: Context) : ViewModel() {
        //code
    }
    

    并且在您的片段活动中以这种方式实例化

    val taskViewModel: TaskViewModel by viewmodels() 
    

    【讨论】:

      【解决方案3】:

      请检查以下选项:

      1- 你必须有这些依赖:

      //Hilt
      def hilt_version = "2.38.1"
      implementation("com.google.dagger:hilt-android:$hilt_version")
      kapt("com.google.dagger:hilt-android-compiler:$hilt_version")
      kapt("androidx.hilt:hilt-compiler:1.0.0")
      implementation("androidx.hilt:hilt-navigation-compose:1.0.0-alpha03")
      implementation("androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03")
      

      2- 您必须已将此注释添加到您的活动中

      @AndroidEntryPoint
      class MainActivity : ComponentActivity()
      

      3- 你必须像这样在屏幕中注入你的 viewModel

      @Composable
      fun MainScreen(
         viewModel: MainScreenViewModel = hiltViewModel()
      )
      

      【讨论】:

        【解决方案4】:

        更新

        implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
        kapt 'androidx.hilt:hilt-compiler:1.0.0'
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-01-04
          • 1970-01-01
          • 2022-11-14
          • 2021-04-18
          • 1970-01-01
          • 2020-12-19
          相关资源
          最近更新 更多