Dagger2 +Kotlin:lateinit属性尚未初始化

t1qtbnec  于 2023-06-24  发布在  Kotlin
关注(0)|答案(7)|浏览(153)

我尝试将ViewModelFactory注入到我的Activity中,但它一直抛出相同的错误:lateinit属性viewModelFactory尚未初始化。我找不到我可能做错了什么。请参阅上面来自我的类的代码
AppComponent.kt

  1. @Component(modules = [(AppModule::class), (NetworkModule::class), (MainModule::class)])
  2. interface AppComponent {
  3. fun inject(application: TweetSentimentsApplication)
  4. fun inject(mainActivity: MainActivity)
  5. fun context(): Context
  6. fun retrofit(): Retrofit
  7. }

MainModule.kt

  1. @Module
  2. class MainModule {
  3. @Provides
  4. fun mainViewModelFactorty(repository: TweetRepository): MainViewModelFactory = MainViewModelFactory(repository)
  5. @Provides
  6. fun local(database: AppDatabase): TweetLocal = TweetLocal(database)
  7. @Provides
  8. fun remote(tweetService: TweetService): TweetRemote = TweetRemote(tweetService)
  9. @Provides
  10. fun tweetService(retrofit: Retrofit): TweetService = retrofit.create(TweetService::class.java)
  11. @Provides
  12. fun repository(local: TweetLocal, remote: TweetRemote): TweetRepository = TweetRepository(local, remote)
  13. }

MainActivity.kt

  1. class MainActivity : AppCompatActivity() {
  2. @Inject lateinit var viewModelFactory: MainViewModelFactory
  3. private val viewModel: MainViewModel? = null
  4. override fun onCreate(savedInstanceState: Bundle?) {
  5. super.onCreate(savedInstanceState)
  6. setContentView(R.layout.main_activity)
  7. ViewModelProviders.of(this, viewModelFactory).get(MainViewModel::class.java)
  8. viewModel?.init("guuilp")
  9. viewModel?.getTweetList()?.observe(this, Observer {
  10. Toast.makeText(this, it?.size.toString(), Toast.LENGTH_LONG).show()
  11. })
  12. }
  13. }

TweetSentimentsApplication.kt

  1. open class TweetSentimentsApplication: Application(){
  2. companion object {
  3. lateinit var appComponent: AppComponent
  4. }
  5. override fun onCreate() {
  6. super.onCreate()
  7. initDI()
  8. }
  9. private fun initDI() {
  10. appComponent = DaggerAppComponent.builder()
  11. .appModule(AppModule(this))
  12. .build()
  13. }
  14. }
oiopk7p5

oiopk7p51#

在初始化MainActivity时,必须调用在AppComponent中定义的inject(mainActivity: MainActivity)方法,这就是Dagger实际注入所需依赖项的方式。

  1. override fun onCreate(savedInstanceState: Bundle?) {
  2. super.onCreate(savedInstanceState)
  3. setContentView(R.layout.main_activity)
  4. // This is where the dependencies are injected
  5. TweetSentimentsApplication.appComponent.inject(this)
  6. ViewModelProviders.of(this, viewModelFactory).get(MainViewModel::class.java)
  7. ...
  8. }
nimxete2

nimxete22#

另外,请确保您的应用程序名称已添加到AndroidManifest.xml文件中。

  1. <application
  2. android:name=".YourAppName"
  3. ..../>
56lgkhnf

56lgkhnf3#

你也可以这样做:

  1. @Inject
  2. lateinit var viewModelFactory: ViewModelProvider.Factory
  3. val mainViewModel: MainViewModel by lazy {
  4. ViewModelProviders.of(this, viewModelFactory)[MainViewModel::class.java]
  5. }

并使用抽象模块和@ContributesAndroidInjector为Activity,抽象模块为视图模型。使用abstract更有效:

  1. @Module
  2. abstract class AndroidBindingModule {
  3. @ContributesAndroidInjector
  4. internal abstract fun contributesAnActivity(): AnActivity
  5. }
  6. @Module
  7. abstract class ViewModelModule {
  8. //the default factory only works with default constructor
  9. @Binds
  10. @IntoMap
  11. @ViewModelKey(AViewModel::class)
  12. abstract fun bindArtViewModel(aViewModel: AViewModel): ViewModel
  13. @Binds
  14. abstract fun bindViewModelFactory(factory: AViewModelFactory): ViewModelProvider.Factory
  15. }
  16. @Documented
  17. @Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
  18. @Retention(RetentionPolicy.RUNTIME)
  19. @MapKey
  20. internal annotation class ViewModelKey(val value: KClass<out ViewModel>)
展开查看全部
nbnkbykc

nbnkbykc4#

您也可以扩展DaggerAppCompatActivity来代替AppCompatActivity。例如

  1. class MainActivity : DaggerAppCompatActivity() {
  2. @Inject lateinit var viewModelFactory: MainViewModelFactory
  3. private val viewModel: MainViewModel? = null
  4. override fun onCreate(savedInstanceState: Bundle?) {
  5. super.onCreate(savedInstanceState)
  6. setContentView(R.layout.main_activity)
  7. ViewModelProviders.of(this, viewModelFactory).get(MainViewModel::class.java)
  8. viewModel?.init("guuilp")
  9. viewModel?.getTweetList()?.observe(this, Observer {
  10. Toast.makeText(this, it?.size.toString(), Toast.LENGTH_LONG).show()
  11. })
  12. }
  13. }
展开查看全部
xkrw2x1b

xkrw2x1b5#

我的错误是创建了一个新对象,并从中获取了一个组件,例如App().component
因此,在这种情况下,您需要将component字段放在companion object中,并将代码替换为App.component

jw5wzhpr

jw5wzhpr6#

我遇到这个问题是因为inject()方法的错误签名,我错误地将参数类型声明为我的类正在实现的接口,而不是类本身。这导致Dagger的inject()实现为空,因此依赖项没有注入->属性没有初始化。
注入依赖项的类:

  1. interface MyInterface {
  2. ...
  3. }
  4. class MyClass : MyInterface {
  5. @Inject
  6. lateinit var someProperty: SomeType
  7. init {
  8. ...
  9. myComponent.inject(this)
  10. ...
  11. someProperty.doSomething() // error: lateinit property has not been initialized
  12. }
  13. }

错误的inject()声明:

  1. interface MyComponent {
  2. fun inject(x: MyInterface)
  3. }
    • inject()声明中更改参数类型解决了问题。**
  1. interface MyComponent {
  2. fun inject(x: MyClass)
  3. }
展开查看全部
0mkxixxg

0mkxixxg7#

也许你错过了在fragment/activity中实现“Injectable”接口。其将片段/活性标记为可注射的。

相关问题