Как ввести Moshi / Gson в преобразователи типов комнат с помощью Hilt?

Я пробую рукоять, и я хочу ввести моши для сериализации и десериализации.

Вот код образец из репозитория github, в котором не используется di:

open class InfoTypeConverter {

private val moshi = Moshi.Builder().build() //not using dependency injection

  @TypeConverter
  fun fromString(value: String): PokemonInfo.Type? {
    val adapter: JsonAdapter<PokemonInfo.Type> = moshi.adapter(PokemonInfo.Type::class.java)
    return adapter.fromJson(value)
  }

  @TypeConverter
  fun fromInfoType(type: PokemonInfo.Type): String {
    val adapter: JsonAdapter<PokemonInfo.Type> = moshi.adapter(PokemonInfo.Type::class.java)
    return adapter.toJson(type)
  }
}

Я пробую случайные вещи, чтобы ввести это, например, аннотацию, с помощью @ AndroidEntryPoint / @ EntryPoint, и, очевидно, это не работает.


person GnaT    schedule 14.08.2020    source источник


Ответы (1)


Включить Moshi в график зависимостей Hilt так же просто, как добавить этот класс:

@Module
@InstallIn(ApplicationComponent::class)
object DataModule {

  @Singleton
  @Provides
  fun provideMoshi(): Moshi {
      return Moshi.Builder().build()
  }
}

@TypeConverters предназначены для Room базы данных. Если вы хотите использовать для них Moshi от Hilt, вам придется немного попробовать. Один из способов сделать это:

  1. Поместите @TypeConverter функций в статический контекст (объявление object) с инициализатором
object InfoTypeConverter {

    private lateinit var moshi: Moshi

    fun initialize(moshi: Moshi){
        this.moshi = moshi
    }

    
    @TypeConverter
    fun fromString(value: String): PokemonInfo.Type? {
      val adapter: JsonAdapter<PokemonInfo.Type> = moshi.adapter(PokemonInfo.Type::class.java)
      return adapter.fromJson(value)
    }

    @TypeConverter
    fun fromInfoType(type: PokemonInfo.Type): String {
      val adapter: JsonAdapter<PokemonInfo.Type> = moshi.adapter(PokemonInfo.Type::class.java)
      return adapter.toJson(type)
    }
}
  1. Инициализируйте InfoTypeConverter перед созданием базы данных RoomDatabase (здесь используется тот же модуль для этой цели):
@Module
@InstallIn(ApplicationComponent::class)
object DataModule {

  @Singleton
  @Provides
  fun provideMoshi(): Moshi {
      return Moshi.Builder().build()
  }

  @Singleton
  @Provides
  fun provideRoomDatabase(moshi: Moshi): YourDatabase {
      InfoTypeConverter.initialize(moshi)
      val yourDatabase: YourDatabase = /* create your room database here */
      return yourDatabase
  }
}
person Bartek Lipinski    schedule 14.08.2020
comment
Спасибо за ответ! Но разве нет другого способа, подобного полевой инъекции? Я имею в виду, что я использовал коин для ди, в котором вы можете вводить моши, как val moshi: Moshi by Inject() - person GnaT; 14.08.2020
comment
1. Но ведь нужно было также инициализировать Moshi где-то еще, не так ли? Теперь вы также можете вводить моши куда угодно с @Inject. Все это безумие, связанное с инициализацией, вызвано тем, как Room работает с TypeConverters. 2. Это всего лишь один из способов сделать что-то. Вы также можете создать EntryPoint для InfoTypeConverter и ввести туда Moshi, но для меня подход, который я предложил в ответе, более понятен. 3. Койн и кинжал / рукоять - это два очень разных понятия, поэтому, естественно, между ними есть различия. - person Bartek Lipinski; 14.08.2020
comment
Хорошо понял. Спасибо за объяснение. - person GnaT; 14.08.2020