2017-09-04 10 views
5

Dagger2で新しいアーキテクチャコンポーネントを使用しています.ViewModelをFactoryクラスを使用して注入したいと思います。 Factoryクラス自体は注入可能です。これは、FactoryクラスがJavaで定義されているときはうまく動作しますが、Kotlinに変換するとDagger2はコンストラクタのMapを生成する方法を知らず、Javaではその方法を知っています。差異は、変換後、Factoryクラスはjava.util.Mapパッケージではなく、kotlinパッケージのMapを使用することです。 Dagger2にFactoryコンストラクタ用のマップを生成させるにはどうすればよいですか?ここでKotlin + Dagger - ViewModelのマップを挿入する

は、ファクトリクラスが

@ActivityScope 
class MainActivityViewModelFactory @Inject 
constructor(private val creators: Map<Class<out ViewModel>, 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) 
     } 

    } 
} 

だと、これは誤り

Error:java.util.Map<java.lang.Class<? extends android.arch.lifecycle.ViewModel>,? extends javax.inject.Provider<android.arch.lifecycle.ViewModel>> cannot be provided without an @Provides-annotated method. 

である私は、マップを提供するために、モジュールを作成してみましたが、それは助けにはなりませんでした。

@ActivityScope 
@Module 
class MapModule { 
    @Provides 
    fun provideMap(): Map<Class<out ViewModel>, Provider<ViewModel>> = mutableMapOf() 
} 

答えて

7

私はあなたのViewModelFactoryコードビットに変更:

@ActivityScope 
class MainActivityViewModelFactory @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) 
     } 

    } 
} 

あなたはこれを試すことができますか? 私は@JvmSuppressWildcards注釈を追加しました。あなたがチェックすることができます詳細については

https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-jvm-suppress-wildcards/index.html

編集: あなたは私のレポからのライブデモを見つけることができます。https://github.com/savepopulation/dc-tracker

+0

を、私はあなたがJavaの 'Map'が必要とされる' MutableMap'を使用する場合があります推測。コトリンの不変性のため –

+2

あなたは私の脳細胞の集団を保存しました –

関連する問題