From f69111b9b7759cbd45320452ccb9b68915827a6b Mon Sep 17 00:00:00 2001 From: Alex Birkett Date: Tue, 10 Dec 2024 18:11:24 +0100 Subject: [PATCH] Use Compose Multiplaform compatible dependencies Replace Gson with kotlinx.serialization Replace java.util.Date with kotlinx.datetime.Instant --- app/build.gradle.kts | 4 +++- .../example/dadflex/gamescreen/GameScreen.kt | 5 +++-- .../example/dadflex/preferences/Highscore.kt | 7 +++++-- .../dadflex/preferences/PreferencesHelper.kt | 19 +++++++++++------ gradle/libs.versions.toml | 21 ++++++++++++------- 5 files changed, 37 insertions(+), 19 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index fe0e4a5..95c8026 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -2,6 +2,7 @@ plugins { alias(libs.plugins.android.application) alias(libs.plugins.kotlin.android) alias(libs.plugins.kotlin.compose) + kotlin("plugin.serialization") version "2.0.20" } android { @@ -40,7 +41,8 @@ android { } dependencies { - implementation("com.google.code.gson:gson:2.8.9") + implementation(libs.kotlinx.datetime) + implementation(libs.kotlinx.serialization.json) implementation(libs.androidx.core.ktx) implementation(libs.androidx.lifecycle.runtime.ktx) implementation(libs.androidx.activity.compose) diff --git a/app/src/main/java/com/example/dadflex/gamescreen/GameScreen.kt b/app/src/main/java/com/example/dadflex/gamescreen/GameScreen.kt index 015d56b..e55352e 100644 --- a/app/src/main/java/com/example/dadflex/gamescreen/GameScreen.kt +++ b/app/src/main/java/com/example/dadflex/gamescreen/GameScreen.kt @@ -37,7 +37,8 @@ import com.example.dadflex.preferences.HighscoreEntry import com.example.dadflex.preferences.PreferencesHelper import com.example.dadflex.ui.theme.DadflexTheme import kotlinx.coroutines.delay -import java.util.Date +import kotlinx.datetime.Clock +import kotlinx.datetime.Instant @Composable @@ -109,7 +110,7 @@ fun GameScreen( val newHighScoreAdded = highscore.checkAndAddHighscore(HighscoreEntry( name = name, reactionTime = result, - date = Date() + date = Clock.System.now() )) if (newHighScoreAdded){ diff --git a/app/src/main/java/com/example/dadflex/preferences/Highscore.kt b/app/src/main/java/com/example/dadflex/preferences/Highscore.kt index 0c96258..7e754af 100644 --- a/app/src/main/java/com/example/dadflex/preferences/Highscore.kt +++ b/app/src/main/java/com/example/dadflex/preferences/Highscore.kt @@ -1,13 +1,16 @@ package com.example.dadflex.preferences -import java.util.Date +import kotlinx.datetime.Instant +import kotlinx.serialization.Serializable +@Serializable data class HighscoreEntry( val name : String, val reactionTime : Long, - val date : Date + val date : Instant ) +@Serializable class Highscore { private val highscoreList = mutableListOf() diff --git a/app/src/main/java/com/example/dadflex/preferences/PreferencesHelper.kt b/app/src/main/java/com/example/dadflex/preferences/PreferencesHelper.kt index f19af3a..3de3df1 100644 --- a/app/src/main/java/com/example/dadflex/preferences/PreferencesHelper.kt +++ b/app/src/main/java/com/example/dadflex/preferences/PreferencesHelper.kt @@ -1,9 +1,9 @@ package com.example.dadflex.preferences -import com.google.gson.Gson - import android.content.Context import android.content.SharedPreferences +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json object PreferencesHelper { private const val PREFS_NAME = "dadflex_prefs" @@ -25,8 +25,9 @@ object PreferencesHelper { } fun saveHighscore(context: Context, highscore: Highscore) { - val gson = Gson() - val highscoreJson = gson.toJson(highscore) + // Convert to JSON with kotlin serialization + val highscoreJson = Json.encodeToString(highscore) + val editor = getPreferences(context).edit() editor.putString(KEY_HIGHSCORE, highscoreJson) @@ -34,8 +35,14 @@ object PreferencesHelper { } fun getHighscore(context: Context): Highscore { - val gson = Gson() val json = getPreferences(context).getString(KEY_HIGHSCORE, null) ?: return Highscore() - return gson.fromJson(json, Highscore::class.java) + // Decode with kotlin serialization + + return try { + Json.decodeFromString(json) + } catch (e: Exception) { + // Old java.util.Date format e.g 'Dec 10, 2024 4:42:44 PM' can't be parsed :( + Highscore() + } } } \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index bc5de2f..e222a2c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -9,23 +9,28 @@ lifecycleRuntimeKtx = "2.6.1" activityCompose = "1.8.0" composeBom = "2024.04.01" navigationCompose = "2.8.4" +kotlinxDatetime = "0.4.0" +kotlinxSerializationJson = "1.7.3" + [libraries] +androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" } +androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" } androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } -junit = { group = "junit", name = "junit", version.ref = "junit" } -androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" } androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } +androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" } androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" } -androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" } -androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" } +androidx-material3 = { group = "androidx.compose.material3", name = "material3" } +androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigationCompose" } androidx-ui = { group = "androidx.compose.ui", name = "ui" } androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" } +androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" } +androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" } androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" } androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" } -androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" } -androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" } -androidx-material3 = { group = "androidx.compose.material3", name = "material3" } -androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigationCompose" } +junit = { group = "junit", name = "junit", version.ref = "junit" } +kotlinx-datetime = { group = "org.jetbrains.kotlinx", name = "kotlinx-datetime", version.ref = "kotlinxDatetime" } +kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" } [plugins] android-application = { id = "com.android.application", version.ref = "agp" }