Android Kotlin匕首2 ViewModel注入错误

我想在我的项目上使用新的ViewModel从拱门Android库。

我在github上学习了很多示例项目。 最后,我想在我的项目上实现这个架构,但是我无法构建它。

Gradle控制台:

 ....AppComponent.java:6: error: [dagger.android.AndroidInjector.inject(T)] kibar.app.ui.fragment.HomeFragmentViewModel cannot be provided without an @Inject constructor or from an @Provides-annotated method. e: public abstract interface AppComponent { e: ^ e: kibar.app.ui.fragment.vpresenter.home.HomeFragmentViewModel is injected at e: kibar.core.di.ViewModelModule.bindHomeViewModel(model) e: java.util.Map<java.lang.Class<? extends android.arch.lifecycle.ViewModel>,javax.inject.Provider<android.arch.lifecycle.ViewModel>> is injected at e: kibar.core.di.viewmodel.ViewModelFactory.<init>(creators) e: kibar.core.di.viewmodel.ViewModelFactory is injected at e: kibar.app.ui.fragment.HomeFragment.viewModelFactory e: kibar.app.ui.fragment.HomeFragment is injected at e: dagger.android.AndroidInjector.inject(arg0) e: java.lang.IllegalStateException: failed to analyze: org.jetbrains.kotlin.kapt3.diagnostic.KaptError: Error while annotation processing at org.jetbrains.kotlin.analyzer.AnalysisResult.throwIfError(AnalysisResult.kt:57) at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules(KotlinToJVMBytecodeCompiler.kt:138) at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:154) at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:58) at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.java:103) at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.java:51) at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:92) ... ... ... 

代码:

 class App : Application(), HasActivityInjector { @field:Inject lateinit var component: AppComponent @field:Inject lateinit var injector: DispatchingAndroidInjector<Activity> override fun activityInjector() = injector override fun onCreate() { super.onCreate(); DaggerAppComponent.builder() .appModule(AppModule(this)) .build() .apply { inject(this@App); component = this } .inject(this) } } @AppScope @Component( modules = arrayOf( AndroidSupportInjectionModule::class, AppModule::class, ActivityModule::class, ViewModelModule::class, DatabaseModule::class) ) interface AppComponent { interface Builder { @BindsInstance fun application(app: App): Builder fun build(): AppComponent } fun inject(application: App) } @Module class AppModule(private val application: Application) { @Provides @AppScope fun provideApplication(): Application = application @Provides @AppScope @ApplicationContext fun provideContext(): Context = application.applicationContext!! } @Module abstract class ActivityModule { @ContributesAndroidInjector(modules = arrayOf(FragmentModule::class)) abstract fun bindHomeActivity(): HomeActivity } @Module(includes = arrayOf(AppModule::class)) class DatabaseModule { @AppScope @Provides fun provideDatabase(@ApplicationContext context: Context): RoomDatabase = Room.databaseBuilder(context, RoomDatabase::class.java, RoomDatabase.CONS.NAME) .allowMainThreadQueries() .build() } @Module abstract class FragmentModule { @ContributesAndroidInjector abstract fun provideHomeFragment(): HomeFragment } @Module abstract class ViewModelModule { @Binds @IntoMap @ViewModelKey(HomeFragmentViewModel::class) abstract fun bindHomeViewModel(model: HomeFragmentViewModel): ViewModel @Binds abstract fun bindAppViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory } @AppScope 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 { var creator: Provider<out ViewModel>? = creators[modelClass] if (creator == null) { for ((key, value) in creators) { if (modelClass.isAssignableFrom(key)) { creator = value break } } } if (creator == null) { throw IllegalArgumentException("unknown model class " + modelClass) } try { return creator.get() as T } catch (e: Exception) { throw RuntimeException(e) } } } @MustBeDocumented @Target(AnnotationTarget.FUNCTION) @Retention(AnnotationRetention.RUNTIME) @MapKey internal annotation class ViewModelKey(val value: KClass<out ViewModel>) @Scope @Retention(AnnotationRetention.RUNTIME) annotation class AppScope @Qualifier @Retention(AnnotationRetention.RUNTIME) annotation class ApplicationContext class HomeActivity : AppCompatActivity(), HasSupportFragmentInjector{ @Inject lateinit var androidInjector: DispatchingAndroidInjector<Fragment> override fun supportFragmentInjector() = androidInjector override fun onCreate(savedInstanceState: Bundle?) { AndroidInjection.inject(this) super.onCreate(savedInstanceState) ... } fun openHomeFragment() { //to make a quick experiment supportFragmentManager.beginTransaction() .replace(R.id.fragmentLayout, HomeFragment(),"HomeFragment") .addToBackStack(null) .commit(); } } class HomeFragment : Fragment(){ @Inject lateinit var viewModelFactory: ViewModelFactory //@Inject val viewModel by lazy { ViewModelProviders.of(this, viewModelFactory).get(HomeFragmentViewModel::class.java) } override fun onAttach(context: Context?) { AndroidSupportInjection.inject(this) super.onAttach(context) } } class HomeFragmentViewModel() : ViewModel() //project.gradle apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-kapt' apply plugin: 'kotlin-android-extensions' buildscript { repositories { jcenter() mavenCentral() } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version" } } android { compileSdkVersion 27 buildToolsVersion '26.0.2' defaultConfig { minSdkVersion 16 targetSdkVersion 27 applicationId "kibar.app" versionCode 1130 versionName '1.1.0' archivesBaseName = "app-$versionName-$versionCode" multiDexEnabled true javaCompileOptions { annotationProcessorOptions { includeCompileClasspath = true } } } buildTypes { release { debuggable false minifyEnabled true shrinkResources true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' } debug { debuggable true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } packagingOptions { exclude 'META-INF/rxjava.properties' } sourceSets { main.java.srcDirs += 'src/main/kotlin' } } kapt { generateStubs = true } dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') implementation 'com.android.support:multidex:1.0.2' implementation "com.android.support:design:$android_support_version" implementation "com.android.support:appcompat-v7:$android_support_version" implementation "com.android.support:recyclerview-v7:$android_support_version" implementation "com.android.support:cardview-v7:$android_support_version" implementation "com.google.firebase:firebase-ads:$firebase_version" implementation "com.google.firebase:firebase-crash:$firebase_version" implementation "com.google.firebase:firebase-config:$firebase_version" implementation 'com.google.code.gson:gson:2.8.2' implementation 'com.jakewharton.timber:timber:4.6.0' implementation 'io.reactivex.rxjava2:rxandroid:2.0.1' implementation 'com.github.clans:fab:1.6.4' implementation 'com.squareup.retrofit2:retrofit:2.3.0' implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" implementation "android.arch.persistence.room:runtime:$room_version" kapt "android.arch.persistence.room:compiler:$room_version" implementation "android.arch.lifecycle:runtime:1.0.3" implementation "android.arch.lifecycle:extensions:1.0.0-rc1" implementation "android.arch.lifecycle:reactivestreams:1.0.0-rc1" kapt "android.arch.lifecycle:compiler:1.0.0-rc1" implementation "com.google.dagger:dagger:$dagger_version" implementation "com.google.dagger:dagger-android:$dagger_version" implementation "com.google.dagger:dagger-android-support:$dagger_version" kapt "com.google.dagger:dagger-android-processor:$dagger_version" kapt "com.google.dagger:dagger-compiler:$dagger_version" provided 'org.glassfish:javax.annotation:10.0-b28' } apply plugin: 'com.google.gms.google-services' //top.gradle buildscript { ext{ android_support_version = "27.0.0" kotlin_version = "1.1.51" firebase_version = "11.4.2" room_version = "1.0.0-alpha9-1" dagger_version = "2.12" } repositories { jcenter() maven { url "https://maven.google.com" } maven { url "https://jitpack.io" } } dependencies { classpath 'com.android.tools.build:gradle:3.0.0' classpath 'com.google.gms:google-services:3.1.1' } } allprojects { repositories { jcenter() maven { url "https://maven.google.com" } maven { url "https://jitpack.io" } } gradle.projectsEvaluated { tasks.withType(JavaCompile) { options.compilerArgs << "-Xmaxerrs" << "1000" } } } 

任何想法如何解决这个问题?

您没有inject注释构造函数或Provides注释的方法,如您的HomeFragmentViewModel Module 。 所以你得到这个错误。

 class HomeFragmentViewModel @Inject constructor(): ViewModel() 

我想这会帮助你。

就像错误状态一样

 kibar.app.ui.fragment.HomeFragmentViewModel cannot be provided without an @Inject constructor or from an @Provides-annotated method. 

您需要以某种方式提供HomeFragmentViewModel 。 这可以在@Module或使用可注入的构造函数

 class HomeFragmentViewModel @Inject constructor()