カスタムクラス(ターン)からジェネリック型のリストを取得できません。
val turnsType = TypeToken<List<Turns>>() {}.type
val turns = Gson().fromJson(pref.turns, turnsType)
と言いました:
cannot access '<init>' it is 'public /*package*/' in 'TypeToken'
このインラインの楽しみを作成します。
inline fun <reified T> Gson.fromJson(json: String) = this.fromJson<T>(json, object: TypeToken<T>() {}.type)
そして、あなたはこの方法でそれを呼び出すことができます:
val turns = Gson().fromJson<Turns>(pref.turns)
// or
val turns: Turns = Gson().fromJson(pref.turns)
NOTE:このアプローチは、以前のkotlinプラグインバージョンでは不可能でしたが、現在は使用できます。
以前の選択肢:
代替1:
val turnsType = object : TypeToken<List<Turns>>() {}.type
val turns = Gson().fromJson<List<Turns>>(pref.turns, turnsType)
object :
と特定のタイプをfromJson<List<Turns>>
に入れる必要があります
代替2:
@cypressiousが言及しているように、この方法でも実現できます。
inline fun <reified T> genericType() = object: TypeToken<T>() {}.type
使用:
val turnsType = genericType<List<Turns>>()
これにより問題が解決します。
val turnsType = object : TypeToken<List<Turns>>() {}.type
val turns = Gson().fromJson<List<Turns>>(pref.turns, turnsType)
最初の行は、TypeToken
から派生する オブジェクト式 を作成し、そこからJava Type
を取得します。次に、Gson().fromJson
メソッドには、関数の結果に指定されたタイプ(TypeToken
に一致する必要があります)が必要です。上記のように、この作業の2つのバージョンまたは:
val turns: List<Turns> = Gson().fromJson(pref.turns, turnsType)
TypeToken
の作成を簡単にするために、ヘルパー関数を作成できます。ヘルパー関数は inline である必要があり、そのため reified type parameters を使用できます。
inline fun <reified T> genericType() = object: TypeToken<T>() {}.type
これらは、次のいずれかの方法で使用できます。
val turnsType = genericType<List<Turns>>()
// or
val turnsType: List<Turns> = genericType()
そして、プロセス全体をGson
インスタンスの拡張関数にラップできます。
inline fun <reified T> Gson.fromJson(json: String) = this.fromJson<T>(json, object: TypeToken<T>() {}.type)
Gsonを呼び出すだけで、TypeToken
についてまったく心配しないでください:
val turns = Gson().fromJson<Turns>(pref.turns)
// or
val turns: Turns = Gson().fromJson(pref.turns)
ここで、Kotlinは割り当ての一方または他方から型推論を使用し、インライン関数のジェネリックを具体化して(消去なしで)完全な型を通過させ、それを使用してTypeToken
を構築し、呼び出しを行いますGsonへ
別のオプション(他のオプションよりもエレガントに見えるかどうかはわかりません)は、次のような呼び出しです。
turns = Gson().fromJson(allPurchasesString, Array<Turns>::class.Java).toMutableList()
したがって、「純粋なKotlin」ではなく、Java Arrayクラスの1つのライナーを使用しています。
val obj: MutableList<SaleItemResponse> = Gson().fromJson(messageAfterDecrypt,
object : TypeToken<List<SaleItemResponse>>() {}.type)
Kotlinでデータ配列を解析する私の方法です。
これも同様に機能し、より簡単です
inline fun <reified T> Gson.fromJson(json: String) : T =
this.fromJson<T>(json, T::class.Java)
このようなものを使用して、T
をstring
に変換し、String
をT
に戻し、Gson
を使用しました。まさにあなたが探しているものではなく、念のため。
拡張機能の宣言
inline fun <reified T : Any> T.json(): String = Gson().toJson(this, T::class.Java)
inline fun <reified T : Any> String.fromJson(): T = Gson().fromJson(this,T::class.Java)
使用法
// Passing an object to new Fragment
companion object {
private const val ARG_SHOP = "arg-shop"
@JvmStatic
fun newInstance(shop: Shop) =
ShopInfoFragment().apply {
arguments = Bundle().apply {
putString(ARG_SHOP, shop.json())
}
}
}
// Parsing the passed argument
private lateinit var shop: Shop
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
shop = it.getString(ARG_SHOP).fromJson() ?: return
}
}