Android 中使用 Kotlin 的 Dagger:lateinit 属性 viewModelProviderFactory 尚未初始化

Dagger with Kotlin in Android: lateinit property viewModelProviderFactory has not been initialized

我的代码:

  1. 应用程序组件:
@Component(
    modules = [
        AndroidSupportInjectionModule::class,
        ActivityBuildersModule::class,
        ViewModelFactoryModule::class
    ]
)
interface AppComponent : AndroidInjector<BaseApplication> {

    @Component.Builder
    interface Builder {

        @BindsInstance
        fun application(application: Application): Builder

        fun build(): AppComponent
    }
}
  1. ActivityBuildersModule:
@Module
abstract class ActivityBuildersModule {

    @ContributesAndroidInjector(
        modules = [MainActivityViewModelModule::class]
    )
    abstract fun contributeMainActivity(): MainActivity
}
  1. MainActivityViewModelModule:
@Module
abstract class MainActivityViewModelModule {

    @Binds
    @IntoMap
    @ViewModelKey(MainActivityViewModel::class)
    public abstract fun bindMainActivityViewModel(mainActivityViewModel: MainActivityViewModel): ViewModel
}
  1. MainActivityViewModel:
class MainActivityViewModel @Inject constructor(application: Application) : AndroidViewModel(application) {
   // empty for now
}
  1. ViewModelKey(在Java):
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@MapKey
public @interface ViewModelKey {

    Class<? extends ViewModel> value();
}
  1. 主要活动:
class MainActivity : AppCompatActivity() { <-- I made mistake here. I must Extend DaggerAppCompatActivity instead of AppCompatActivity.

//  doesn't work for now
    @Inject
    lateinit var viewModelProviderFactory: ViewModelProviderFactory

    lateinit var mainActivityViewModel: MainActivityViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContentView(R.layout.activity_main)

        mainActivityViewModel = ViewModelProvider(this, viewModelProviderFactory).get(MainActivityViewModel::class.java)

        setMainFragment()
    }

    private fun setMainFragment() {
        // my code
    }
}

它给我一个错误:lateinit 属性 viewModelProviderFactory 尚未初始化。

相同的代码在 Java 的另一个项目中工作正常。

扩展 DaggerAppCompatActivity 而不是 AppCompatActivity

我在这里可能是错的,但我认为您的 viewModelModule 中需要一个 ViewModelFactory,如下所示:

@Module
abstract class MainActivityViewModelModule {

    @Binds
    @IntoMap
    @ViewModelKey(MainActivityViewModel::class)
    public abstract fun bindMainActivityViewModel(mainActivityViewModel: MainActivityViewModel): ViewModel


    @Binds
    abstract fun provideViewModelFactory(
        factory: ViewModelFactory
    ): ViewModelProvider.Factory

}
class ViewModelFactory @Inject constructor(
    private val creators: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>
) : ViewModelProvider.Factory {
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        val creator = creators[modelClass] ?: creators.entries.firstOrNull {
            modelClass.isAssignableFrom(it.key)
        }?.value ?: throw IllegalArgumentException("unknown model class $modelClass")
        try {
            @Suppress("UNCHECKED_CAST")
            return creator.get() as T
        } catch (e: Exception) {
            throw RuntimeException(e)
        }

    }
}