Параметры о нестандартном адаптере Moshi - PullRequest
1 голос
/ 19 октября 2019

Я использую Моши с Котлиным. В соответствии с README , пользовательский адаптер типа может выглядеть так:

class CardAdapter {
  @ToJson String toJson(Card card) {
    return card.rank + card.suit.name().substring(0, 1);
  }

  @FromJson Card fromJson(String card) {
    return //...
  }
}

Он получает объект или строку, преобразуется в другой. Но я сделал адаптер следующим образом:

class ConfigAdapter{

    @ToJson
    fun toJson(writer: JsonWriter, value: WfBaseConfig?) {
        val moshi = Moshi.Builder().build()
        when (value) {
            is BoolConfig -> moshi.adapter(BoolConfig::class.java).toJson(writer, value)
            // Other types ...
            else -> throw
            IllegalArgumentException("Unknown wf config type: ${value::class.java.simpleName}")
        }
    }

    @FromJson
    fun fromJson(reader: JsonReader): BaseConfig? {
        var type = ""
        val copy = reader.peekJson()
        copy.readObject {
            when (copy.selectName(JsonReader.Options.of("type"))) {
                0 -> type = copy.nextString()
                else -> copy.skipNameAndValue()
            }
        }
        val moshi = Moshi.Builder().build()
        return when (type) {
            "boole" -> moshi.adapter(BoolConfig::class.java).fromJson(reader)
            // Other operations...
            else -> {
                e("Unknown config type: $type")
                null
            }
        }
    }

    private fun JsonReader.skipNameAndValue() {
        skipName()
        skipValue()
    }
}

Оригинальный формат JSON:

[
 {
    "id": "show_weather",
    "type": "boole",
    "title_en": "Show Weather",
    "def": false
 },
 {
    "id": "text_size",
    "type": "list",
    "title_en": "Text Size",
    "item_type": "text",
    "def": 1,
    "data": [{
            "id": 0,
            "title_en": "Large",
        },
        {
            "id": 1,
            "title_en": "Middle",
        },
        {
            "id": 2,
            "title_en": "Small",
        }
    ]
 }
]

Объяснение: Формат каждого объекта определяется type, если он был list, формат data будет определен как item_type.

Используйте его:

val listType = Types.newParameterizedType(List::class.java, BaseConfig::class.java)
val moshi = Moshi.Builder().add(ConfigAdapter()).build()
return moshi.adapter<List<BaseConfig>>(listType).fromJson(conf)

Это тоже хорошо работает. Логика разбора не важна. Я просто не могу понять, какой тип или параметры мы можем использовать в toJson() или fromJson(). Мне не удалось найти какие-либо документы по этому поводу.

Кстати, эти параметры были сгенерированы JsonAdapter<T>, но я наконец удалил 'экстент', потому что он вызывает Unable to resolve Lcom/squareup/moshi/JsonAdapter; annotation class 7823 предупреждение logcat. Я также очень озадачен тем, когда мне следует расширить JsonAdapter класс или просто использовать @ToJson / @FromJson аннотаций.

Любые объяснения приветствуются.

...