2017-09-26 12 views
1

私はアンドロイドライブラリから新しいViewModelを注入するために私のAndroidアプリケーションでdagger 2を使用しようとしています。私はこのサンプルhttps://github.com/googlesamples/android-architecture-components/tree/e33782ba54ebe87f7e21e03542230695bc893818/GithubBrowserSampleに表示されるものとKotlin dagger 2 Android ViewModel注入エラー

は、私がこれを使用する必要があります:

@MustBeDocumented 
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CONSTRUCTOR, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER) 
@Retention(AnnotationRetention.RUNTIME) 
@MapKey 
internal annotation class ViewModelKey(val value: KClass<out ViewModel>) 

@Module 
abstract class ViewModelModule { 
    @Binds 
    @IntoMap 
    @ViewModelKey(LoginViewModel::class) 
    internal abstract fun bindLoginViewModel(viewModel: LoginViewModel): LoginViewModel 

    @Binds 
    @IntoMap 
    @ViewModelKey(MainMenuViewModel::class) 
    internal abstract fun bindSearchViewModel(viewModel: MainMenuViewModel): MainMenuViewModel 

    @Binds 
    internal abstract fun bindViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory 
} 

@ApplicationScope 
@Component(modules = arrayOf(ApplicationModule::class, NetworkModule::class, ViewModelModule::class)) 
interface ApplicationComponent { 
    fun plusActivityComponent(activityModule: ActivityModule): ActivityComponent 
    fun inject(application: LISAApplication) 

} 

をそして、私の工場は次のとおりです。

@ApplicationScope 
class ViewModelFactory @Inject constructor(private val creators: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>) : ViewModelProvider.Factory { 

    @Suppress("UNCHECKED_CAST") 
    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) 
     } 

    } 
} 

しかし、プロジェクトがコンパイルされません:(私はこのエラーを持っています(マップ< ...>は、@ Provides-annotatedメソッドなしでは提供できません。):

Using Kotlin incremental compilation 
:mobile:transformDataBindingWithDataBindingMergeArtifactsForDebug UP-TO-DATE 
:mobile:kaptDebugKotlin 
e: /Users/jaumard/LISAProjects/LISA/mobile/build/tmp/kapt3/stubs/debug/com/mylisabox/lisa/dagger/components/ApplicationComponent.java:6: error: [com.mylisabox.lisa.dagger.components.ActivityComponent.inject(com.mylisabox.lisa.common.BaseActivity)] java.util.Map<java.lang.Class<? extends android.arch.lifecycle.ViewModel>,javax.inject.Provider<android.arch.lifecycle.ViewModel>> cannot be provided without an @Provides-annotated method. 
e: 

e: public abstract interface ApplicationComponent { 
e:    ^
e:  java.util.Map<java.lang.Class<? extends android.arch.lifecycle.ViewModel>,javax.inject.Provider<android.arch.lifecycle.ViewModel>> is injected at 
e:   com.mylisabox.lisa.dagger.ViewModelFactory.<init>(creators) 
e:  com.mylisabox.lisa.dagger.ViewModelFactory is injected at 
e:   com.mylisabox.lisa.common.BaseActivity.factory 
e:  com.mylisabox.lisa.common.BaseActivity is injected at 
e:   com.mylisabox.lisa.dagger.components.ActivityComponent.inject(activity) 
e: /Users/jaumard/LISAProjects/LISA/mobile/build/tmp/kapt3/stubs/debug/com/mylisabox/lisa/dagger/components/ActivityComponent.java:4: error: com.mylisabox.lisa.dagger.components.ActivityComponent scoped with @com.mylisabox.network.dagger.annotations.ActivityScope may not reference bindings with different scopes: 
e: 

これをどうやって解決するか考えてみましょうか?

+0

Kotlinで '@Binds'アノテーションを使用して同様の問題が発生しました。抽象メソッドではなく@XCommandで具体的な実装を返すように変更する必要がありました。誰かが解決策を提供できるかどうかは良いだろう。 –

+0

こんにちは、すべての抽象メソッドを削除し、@Providesを代わりに使用することを意味しますか?魔女は、マップを手動で構築する必要があることを意味しますか? – jaumard

+0

私のための答えを見つけて、それを確認してください、それもあなたのために働くことを願って – jaumard

答えて

2

私は問題を見つけました。私のViewModelModuleの下に問題がありました。ViewModelを抽象メソッドから直接必要な型に戻す必要があります。

@Module 
abstract class ViewModelModule { 
    @Binds 
    @IntoMap 
    @ViewModelKey(LoginViewModel::class) 
    internal abstract fun bindLoginViewModel(viewModel: LoginViewModel): ViewModel 

    @Binds 
    @IntoMap 
    @ViewModelKey(MainMenuViewModel::class) 
    internal abstract fun bindSearchViewModel(viewModel: MainMenuViewModel): ViewModel 

    @Binds 
    internal abstract fun bindViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory 
} 
+1

私はこれをやったが、それでも失敗した。私は、 'Provider >'に '@ JvmSuppressWildcards'アノテーションを付けてアノテーションを付けなければなりませんでした。 'ViewModelProvider.Factory {' –

+0

あなたが正しいです、@ JvmSuppressWildcardsは必須です、私はそれを私の中に入れませんでした。私の質問の私の工場コード上に既に存在していたので答えてください – jaumard

関連する問題