Skip to content

Commit 26e1633

Browse files
authored
Merge pull request #359 from hannesa2/kotlinx.serialization
Move from Gson to kotlinx.serialization
2 parents f8c9f7b + e130674 commit 26e1633

15 files changed

Lines changed: 169 additions & 816 deletions

githubAppUpdate/build.gradle.kts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget
33
plugins {
44
id("com.android.library")
55
id("maven-publish")
6+
kotlin("plugin.serialization") version "2.3.20"
67
}
78

89
android {
910
namespace = "info.hannes.github"
1011
compileSdk = 36
1112
defaultConfig {
1213
minSdk = 23
14+
consumerProguardFiles("proguard-rules.pro")
1315
}
1416
compileOptions {
1517
sourceCompatibility = JavaVersion.VERSION_17
@@ -31,12 +33,12 @@ base {
3133

3234
dependencies {
3335
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.3.20")
34-
implementation("com.google.code.gson:gson:2.13.2")
36+
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.8.1")
3537
implementation("androidx.work:work-runtime-ktx:2.11.2")
3638

3739
implementation("com.squareup.retrofit2:retrofit:3.0.0")
3840
implementation("androidx.appcompat:appcompat:1.7.1")
39-
implementation("com.squareup.retrofit2:converter-gson:3.0.0")
41+
implementation("com.squareup.retrofit2:converter-kotlinx-serialization:3.0.0")
4042
implementation("androidx.preference:preference-ktx:1.2.1")
4143
api("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2")
4244
api("androidx.lifecycle:lifecycle-runtime-ktx:2.10.0")

githubAppUpdate/proguard-rules.pro

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Keep Kotlin metadata for coroutines
22
-keep class kotlin.Metadata { *; }
33
-keepattributes RuntimeVisibleAnnotations
4-
-keepattributes *Annotation*
4+
-keepattributes *Annotation*,InnerClasses,AnnotationDefault
55

66
# Keep coroutine related classes
77
-keepclassmembernames class kotlinx.** {
@@ -14,7 +14,6 @@
1414

1515
# Don't obfuscate Kotlin metadata
1616
-keepattributes SourceFile,LineNumberTable
17-
-renamesourcefileattribute SourceFile
1817

1918
# Keep synthetic methods for Kotlin coroutines
2019
-keepclassmembers class ** {
@@ -31,3 +30,35 @@
3130
# Keep lifecycle coroutine scope
3231
-keep class androidx.lifecycle.** { *; }
3332
-keepclassmembers class androidx.lifecycle.** { *; }
33+
34+
##------------------ kotlinx.serialization ------------------
35+
36+
# Keep @Serializable companion objects and their serializer() methods
37+
-if @kotlinx.serialization.Serializable class **
38+
-keepclassmembers class <1> {
39+
static <1>$Companion Companion;
40+
}
41+
42+
# Keep serializer() on named companion objects of serializable classes
43+
-if @kotlinx.serialization.Serializable class ** {
44+
static **$* *;
45+
}
46+
-keepclassmembers class <2>$<3> {
47+
kotlinx.serialization.KSerializer serializer(...);
48+
}
49+
50+
# Keep INSTANCE.serializer() for serializable objects
51+
-if @kotlinx.serialization.Serializable class ** {
52+
public static ** INSTANCE;
53+
}
54+
-keepclassmembers class <1> {
55+
public static <1> INSTANCE;
56+
kotlinx.serialization.KSerializer serializer(...);
57+
}
58+
59+
# Keep serialization descriptor fields
60+
-keepclassmembers class kotlinx.serialization.internal.** { *; }
61+
62+
# Suppress notes about kotlinx.serialization internals
63+
-dontnote kotlinx.serialization.**
64+
-dontwarn kotlinx.serialization.**

githubAppUpdate/src/main/java/info/hannes/github/AppUpdateHelper.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ object AppUpdateHelper {
6868
prefs.edit { putLong(key, System.currentTimeMillis()) }
6969

7070
versionList.body()?.firstOrNull()?.let { release ->
71-
val assetApk = release.assets.find { it.name.endsWith("release.apk") }
71+
val assetApk = release.assets.find { it.name?.endsWith("release.apk") == true }
7272

7373
Log.d("AppUpdateHelper", release.tagName + " > " + currentVersionName + " " + (release.tagName > currentVersionName))
7474
if (release.tagName > currentVersionName) {
@@ -96,7 +96,7 @@ object AppUpdateHelper {
9696
val versionList = requestVersionsSync(gitRepoUrl, token)
9797

9898
versionList.body()?.firstOrNull()?.let { release ->
99-
val assetApk = release.assets.find { it.name.endsWith("release.apk") }
99+
val assetApk = release.assets.find { it.name?.endsWith("release.apk") == true }
100100

101101
Log.d("AppUpdateHelper", release.tagName + " > " + currentVersionName + " " + (release.tagName > currentVersionName))
102102
val text = "You use version $currentVersionName\n" +
@@ -112,12 +112,12 @@ object AppUpdateHelper {
112112
}
113113
}
114114

115-
private fun requestVersionsSync(gitRepoUrl: String, token: String? = null): Response<MutableList<GithubVersion>> {
115+
private fun requestVersionsSync(gitRepoUrl: String, token: String? = null): Response<List<GithubVersion>> {
116116
val client = GithubClient(HttpLoggingInterceptor.Level.BODY, token)
117117
return client.github.getGithubVersions(gitRepoUrl.user(), gitRepoUrl.repo()).execute()
118118
}
119119

120-
private suspend fun requestGithubVersions(gitRepoUrl: String, token: String? = null): Response<MutableList<GithubVersion>> {
120+
private suspend fun requestGithubVersions(gitRepoUrl: String, token: String? = null): Response<List<GithubVersion>> {
121121
val versionList = withContext(Dispatchers.Default) {
122122
val client = GithubClient(HttpLoggingInterceptor.Level.BODY, token)
123123
client.github.getGithubVersions(gitRepoUrl.user(), gitRepoUrl.repo()).execute()
@@ -147,15 +147,15 @@ object AppUpdateHelper {
147147
dialog.dismiss()
148148
}
149149
.setPositiveButton(activity.getString(R.string.showRelease)) { dialog, _ ->
150-
val uriUrl = release.htmlUrl.toUri()
150+
val uriUrl = release.htmlUrl.orEmpty().toUri()
151151
Log.d("open", uriUrl.toString())
152152
activity.startActivity(Intent(Intent.ACTION_VIEW, uriUrl))
153153
dialog.dismiss()
154154
}
155155

156156
assetApk?.let {
157157
dialog.setNeutralButton(activity.getString(R.string.directDownload)) { dialog, _ ->
158-
val uriUrl = it.browserDownloadUrl.toUri()
158+
val uriUrl = it.browserDownloadUrl.orEmpty().toUri()
159159
Log.d("open", uriUrl.toString())
160160
activity.startActivity(Intent(Intent.ACTION_VIEW, uriUrl))
161161
dialog.dismiss()

githubAppUpdate/src/main/java/info/hannes/github/GithubRestServiceCreationHelper.kt

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
package info.hannes.github
22

3-
import com.google.gson.Gson
4-
import com.google.gson.GsonBuilder
3+
import kotlinx.serialization.json.Json
4+
import okhttp3.MediaType.Companion.toMediaType
55
import okhttp3.OkHttpClient
66
import okhttp3.logging.HttpLoggingInterceptor
77
import retrofit2.Retrofit
8-
import retrofit2.converter.gson.GsonConverterFactory
8+
import retrofit2.converter.kotlinx.serialization.asConverterFactory
99

1010
internal object GithubRestServiceCreationHelper {
1111

1212
private var httpLoggingInterceptor: HttpLoggingInterceptor = HttpLoggingInterceptor()
1313

14-
init {
15-
httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.NONE
14+
private val json = Json {
15+
ignoreUnknownKeys = true
16+
coerceInputValues = true
1617
}
1718

18-
private fun createGson(): Gson {
19-
return GsonBuilder().serializeNulls()
20-
.create()
19+
init {
20+
httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.NONE
2121
}
2222

2323
fun <T> createGithubService(retrofitInterface: Class<T>, logLevel: HttpLoggingInterceptor.Level, token: String? = null): T {
@@ -34,11 +34,10 @@ internal object GithubRestServiceCreationHelper {
3434
val client = clientHttp
3535
.build()
3636

37-
val gson = createGson()
3837
val retrofit = Retrofit.Builder()
3938
.baseUrl("https://api.github.com")
4039
.client(client)
41-
.addConverterFactory(GsonConverterFactory.create(gson))
40+
.addConverterFactory(json.asConverterFactory("application/json; charset=UTF-8".toMediaType()))
4241
.build()
4342

4443
return retrofit.create(retrofitInterface)

githubAppUpdate/src/main/java/info/hannes/github/IGithub.java

Lines changed: 0 additions & 19 deletions
This file was deleted.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package info.hannes.github
2+
3+
import info.hannes.github.model.GithubVersion
4+
import retrofit2.Call
5+
import retrofit2.http.GET
6+
import retrofit2.http.Headers
7+
import retrofit2.http.Path
8+
9+
interface IGithub {
10+
@GET("/repos/{githubUser}/{githubRepo}/releases")
11+
@Headers("Accept: application/json")
12+
fun getGithubVersions(
13+
@Path("githubUser") githubUser: String,
14+
@Path("githubRepo") githubRepo: String
15+
): Call<List<GithubVersion>>
16+
}

githubAppUpdate/src/main/java/info/hannes/github/Notify.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ internal object Notify {
4242
//the message that will be displayed as the ticker
4343
val ticker = "$contentTitle $messageString"
4444

45-
val showUrl = release.htmlUrl.toUri()
45+
val showUrl = release.htmlUrl.orEmpty().toUri()
4646
val showPendingIntent = PendingIntent.getActivity(context, 0, Intent(Intent.ACTION_VIEW, showUrl), PENDING_INTENT_FLAGS)
4747

4848
//build the notification
@@ -58,7 +58,7 @@ internal object Notify {
5858
.addAction(R.drawable.githib_logo, context.getString(R.string.showRelease), showPendingIntent)
5959

6060
assetApk?.let {
61-
val uriUrl = it.browserDownloadUrl.toUri()
61+
val uriUrl = it.browserDownloadUrl.orEmpty().toUri()
6262
val directPendingIntent = PendingIntent.getActivity(context, 0, Intent(Intent.ACTION_VIEW, uriUrl), PENDING_INTENT_FLAGS)
6363
notificationCompat.addAction(R.drawable.githib_logo, context.getString(R.string.directDownload), directPendingIntent)
6464
}

githubAppUpdate/src/main/java/info/hannes/github/model/Asset.java

Lines changed: 0 additions & 152 deletions
This file was deleted.

0 commit comments

Comments
 (0)