无法使用Hilt创建MainViewModel实例

4

我正在使用一个简单的项目测试 Hilt,我的目标是使用 Hilt 生成 MainViewModel 的实例,以下是我迄今为止所做的:

MainActivity

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
 ...
}

主碎片

@AndroidEntryPoint
class MainFragment : Fragment(),MainAdapter.OnTragoClickListener {

    private val viewModel by activityViewModels<MainViewModel>()

...
}

主视图模型

class MainViewModel @ViewModelInject constructor(private val repo:Repo):ViewModel(){
...
}

RepoImpl

class RepoImpl @Inject constructor(private val dataSource: DataSource): Repo {
...
}

DataSourceImpl

class DataSourceImpl @Inject constructor(private val tragosDao: TragosDao): DataSource{
...
}

现在,这是应用程序遵循的架构,其中RepoDataSource是我使用的简单接口。

因此,在此之后,我生成了Hilt所需生成实例的所有内容。

BaseApplication

@HiltAndroidApp
class BaseApplication: Application() {
}

AppModule

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

    @Singleton
    @Provides
    fun provideRoomInstance(
        @ApplicationContext context: Context
    ) = Room.databaseBuilder(
            context,
            AppDatabase::class.java,
            "tabla_tragos")
            .build()

    @Singleton
    @Provides
    fun provideTragosDao(db: AppDatabase) = db.tragoDao()

}

上述模块提供了 tragoDao() 方法,以便我可以在 DataSourceImpl 中访问它。由于我需要这个数据库的唯一实例,因此我在其提供类上使用了 @Singleton 注解。
然后,我只需创建另一个模块,让 Hilt 知道上述接口的实现即可。
@Module
@InstallIn(ActivityRetainedComponent::class)
abstract class ActivityModule {

    @Binds
    abstract fun bindDataSource(dataSource:DataSourceImpl): DataSource

    @Binds
    abstract fun bindRepo(repo: RepoImpl): Repo

}

由于我需要一个 MainViewModel 实例,所以我将这个模块作用域限定为 ActivityRetainedComponent

编译应用程序后,我收到以下错误:

java.lang.RuntimeException: 无法创建类 com.g.tragosapp.ui.viewmodel.MainViewModel 的实例

依赖项

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
apply plugin: 'dagger.hilt.android.plugin'

dependencies {
  implementation fileTree(dir: "libs", include: ["*.jar"])
  implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
  implementation 'androidx.core:core-ktx:1.3.0'
  implementation 'androidx.appcompat:appcompat:1.1.0'
  implementation 'androidx.constraintlayout:constraintlayout:1.1.3'

  //Navigation Components
  implementation "androidx.navigation:navigation-fragment-ktx:2.3.0"
  implementation "androidx.navigation:navigation-ui-ktx:2.3.0"
  implementation 'androidx.legacy:legacy-support-v4:1.0.0'

  //ViewModel y LiveData
  implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'

  // KTX - Viewmodel Y Livedata
  implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'
  implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.0-alpha05"

  implementation "androidx.fragment:fragment-ktx:1.2.5"
  implementation "androidx.activity:activity-ktx:1.1.0"

  //utils
  implementation 'com.github.bumptech.glide:glide:4.11.0'
  annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'

  //Corutinas
  implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.3"

  //Retrofit
  implementation 'com.squareup.retrofit2:retrofit:2.6.0'
  implementation 'com.google.code.gson:gson:2.8.5'
  implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
  implementation 'com.squareup.okhttp3:logging-interceptor:3.12.0'

  implementation 'com.github.chrisbanes:PhotoView:2.3.0'

  //Room
  implementation 'androidx.room:room-ktx:2.2.5'
  implementation "androidx.room:room-runtime:2.2.5"
  kapt "androidx.room:room-compiler:2.2.5"

  //Hilt
  implementation "com.google.dagger:hilt-android:2.28-alpha"
  kapt "com.google.dagger:hilt-android-compiler:2.28-alpha"
  implementation 'androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha02'


  testImplementation 'junit:junit:4.12'
  androidTestImplementation 'androidx.test.ext:junit:1.1.1'
  androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}

我还添加了

  implementation "androidx.fragment:fragment-ktx:1.2.5"
  implementation "androidx.activity:activity-ktx:1.1.0"
  implementation "androidx.core:core:1.3.1"

这并没有产生任何不同。


2
添加kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha02' - IR42
哇,这个可行了,谢谢。 - SNM
1个回答

2
class RepoImpl

应该是:

@Singleton class RepoImpl

同样适用于DataSourceImpl

接着,将 @InstallIn(ActivityRetainedComponent::class) 改为 @InstallIn(SingletonComponent::class)(曾经是ApplicationComponent)

同时确保在撰写时具备以下所有依赖项:

buildscript {
    ext {
        dagger_version = '2.41'
    }

dependencies {
    classpath "com.google.dagger:hilt-android-gradle-plugin:$dagger_version"
}

并且

apply plugin: 'dagger.hilt.android.plugin'
apply plugin: 'kotlin-kapt'

implementation "com.google.dagger:dagger:$dagger_version"
kapt "com.google.dagger:dagger-compiler:$dagger_version"
implementation "com.google.dagger:hilt-android:$dagger_version"
kapt "com.google.dagger:hilt-android-compiler:$dagger_version"
kaptTest "com.google.dagger:hilt-android-compiler:$dagger_version"
kaptAndroidTest "com.google.dagger:hilt-android-compiler:$dagger_version"
kapt 'androidx.hilt:hilt-compiler:1.0.0'

似乎我没有SingletonComponent :: class可供安装,另外,做这些类单例有什么区别?谢谢。 - SNM
标记单例并添加ApplicationComponent会导致创建实例时出现相同的错误。 - SNM
如果将它们设置为单例模式,那么它们将与我正在安装的组件共享相同的作用域。这应该可以减少一些错误的可能性。ApplicationComponent 正在被重命名为 SingletonComponent,在您当前的版本中可能会有所不同。如果 HiltViewModelProviderFactory 仍未被使用,请检查是否已经应用了插件以实际运行 Hilt gradle 插件。 - EpicPandaForce
@EpicPandaForce,你能帮我解决一个疑问吗?Hilt不能与Presenter或View类一起使用吗? - Ravindra Kushwaha
@RavindraKushwaha 我不可能知道你的设置,因此我无法回答你的问题,也不知道你在寻找什么。 "Presenters" 在Android开发中并不是常见的。 - EpicPandaForce
@EpicPandaForce,你能否帮忙看一下这个问题 https://stackoverflow.com/q/67761348/3946958 。我已经在那里发布了问题。谢谢。 - Ravindra Kushwaha

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接