メモ > 技術 > IDE: AndroidStudio > アプリの作成(Jetpack Compose / JSONを扱う)
アプリの作成(Jetpack Compose / JSONを扱う)
【Kotlin】Kotlin Serialization で JSON をパースする - Tatsuro のテックブログ
https://tatsurotech.hatenablog.com/entry/kotlin/serialization-basic
KotlinでJSONをシリアライズ/デシリアライズする | Konsome Engineering
https://engineering.konso.me/articles/kotlin-json-serialization/
主に上記のページを参照したが、実行しても
「Type mismatch: inferred type is Fruit but SerializationStrategy<TypeVariable(T)> was expected」
というエラーになった
以下のようにすると、エラーにならずに実行できるようになった
build.gradle で以下を追加する
plugins {
〜略〜
id 'org.jetbrains.kotlin.plugin.serialization' version '1.6.20' apply false // 追加
}
app/build.gradle で以下を追加する
plugins {
〜略〜
id 'org.jetbrains.kotlin.plugin.serialization' // 追加
}
dependencies {
〜略〜
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.2" // 追加
以下のとおりプログラムを作成する
@Composable
fun MainScreen() {
// クラスのシリアライズとデシリアライズ
val apple = Fruit("リンゴ", 100, 1)
val json1 = Json.encodeToString(Fruit.serializer(), apple)
val fruit = Json.decodeFromString(Fruit.serializer(), json1)
println(fruit.name) // 「リンゴ」が出力される
// リストのシリアライズとデシリアライズ
val list = listOf(Fruit("リンゴ", 100, 1), Fruit("ミカン", 500, 3))
val json2 = Json.encodeToString(ListSerializer(Fruit.serializer()), list)
val fruits = Json.decodeFromString(ListSerializer(Fruit.serializer()), json2)
println(fruits[0].name) // 「リンゴ」が出力される
Text("Hello!")
}
@Serializable
data class Fruit(
@SerialName("name")
val name: String,
@SerialName("value")
val value: Int,
@SerialName("amount")
val amount: Int
)
「@Serializable」は省略できないが、「@SerialName("name")」はシリアライズ前後で名前が同じなら省略できる
■シリアライズして保存する
以下のようにすれば、シリアライズしたうえでDataStoreに保存できる
val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "data")
@Composable
fun MainScreen() {
val context = LocalContext.current
// クラスのシリアライズとデシリアライズ
val apple = Fruit("リンゴ", 100, 1)
val json1 = Json.encodeToString(Fruit.serializer(), apple)
val fruit = Json.decodeFromString(Fruit.serializer(), json1)
println(fruit.name) // 「リンゴ」が出力される
// リストのシリアライズとデシリアライズ
val list = listOf(Fruit("リンゴ", 100, 1), Fruit("ミカン", 500, 3))
val json2 = Json.encodeToString(ListSerializer(Fruit.serializer()), list)
val fruits = Json.decodeFromString(ListSerializer(Fruit.serializer()), json2)
println(fruits[0].name) // 「リンゴ」が出力される
/*
// DataStoreから復元する場合
runBlocking(Dispatchers.IO) {
val savedJson = getData(context)
val savedFruits = Json.decodeFromString(ListSerializer(Fruit.serializer()), savedJson)
println(savedFruits[0].name) // 「リンゴ」が出力される
}
*/
// DataStoreに保存する場合
runBlocking(Dispatchers.IO) {
putData(context, json2)
}
Text("Hello!")
}
@Serializable
data class Fruit(
val name: String,
val value: Int,
val amount: Int
)
suspend fun putData(context: Context, data: String) {
try {
context.dataStore.edit { entries ->
entries[stringPreferencesKey("data")] = data
}
} catch (e: IOException) {
Log.d("putData", data)
}
}
suspend fun getData(context: Context): String {
var data = ""
try {
data = context.dataStore.data.first()[stringPreferencesKey("data")].toString()
} catch (e: IOException) {
Log.d("getText", data)
}
return data
}