فهرست منبع

Singleton instance of Json serializer

arkon 4 سال پیش
والد
کامیت
d21c147203

+ 3 - 0
app/src/main/java/eu/kanade/tachiyomi/AppModule.kt

@@ -13,6 +13,7 @@ import eu.kanade.tachiyomi.network.NetworkHelper
 import eu.kanade.tachiyomi.source.SourceManager
 import kotlinx.coroutines.GlobalScope
 import kotlinx.coroutines.launch
+import kotlinx.serialization.json.Json
 import uy.kohesive.injekt.api.InjektModule
 import uy.kohesive.injekt.api.InjektRegistrar
 import uy.kohesive.injekt.api.addSingleton
@@ -44,6 +45,8 @@ class AppModule(val app: Application) : InjektModule {
 
         addSingletonFactory { Gson() }
 
+        addSingletonFactory { Json { ignoreUnknownKeys = true } }
+
         // Asynchronously init expensive components for a faster cold start
 
         GlobalScope.launch { get<PreferencesHelper>() }

+ 6 - 3
app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadPendingDeleter.kt

@@ -8,6 +8,7 @@ import kotlinx.serialization.Serializable
 import kotlinx.serialization.decodeFromString
 import kotlinx.serialization.encodeToString
 import kotlinx.serialization.json.Json
+import uy.kohesive.injekt.injectLazy
 
 /**
  * Class used to keep a list of chapters for future deletion.
@@ -16,6 +17,8 @@ import kotlinx.serialization.json.Json
  */
 class DownloadPendingDeleter(context: Context) {
 
+    private val json: Json by injectLazy()
+
     /**
      * Preferences used to store the list of chapters to delete.
      */
@@ -49,7 +52,7 @@ class DownloadPendingDeleter(context: Context) {
             val existingEntry = preferences.getString(manga.id!!.toString(), null)
             if (existingEntry != null) {
                 // Existing entry found on preferences, decode json and add the new chapter
-                val savedEntry = Json.decodeFromString<Entry>(existingEntry)
+                val savedEntry = json.decodeFromString<Entry>(existingEntry)
 
                 // Append new chapters
                 val newChapters = savedEntry.chapters.addUniqueById(chapters)
@@ -65,7 +68,7 @@ class DownloadPendingDeleter(context: Context) {
         }
 
         // Save current state
-        val json = Json.encodeToString(newEntry)
+        val json = json.encodeToString(newEntry)
         preferences.edit {
             putString(newEntry.manga.id.toString(), json)
         }
@@ -97,7 +100,7 @@ class DownloadPendingDeleter(context: Context) {
     private fun decodeAll(): List<Entry> {
         return preferences.all.values.mapNotNull { rawEntry ->
             try {
-                (rawEntry as? String)?.let { Json.decodeFromString<Entry>(it) }
+                (rawEntry as? String)?.let { json.decodeFromString<Entry>(it) }
             } catch (e: Exception) {
                 null
             }

+ 3 - 2
app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadStore.kt

@@ -28,6 +28,7 @@ class DownloadStore(
      */
     private val preferences = context.getSharedPreferences("active_downloads", Context.MODE_PRIVATE)
 
+    private val json: Json by injectLazy()
     private val db: DatabaseHelper by injectLazy()
 
     /**
@@ -109,7 +110,7 @@ class DownloadStore(
      */
     private fun serialize(download: Download): String {
         val obj = DownloadObject(download.manga.id!!, download.chapter.id!!, counter++)
-        return Json.encodeToString(obj)
+        return json.encodeToString(obj)
     }
 
     /**
@@ -119,7 +120,7 @@ class DownloadStore(
      */
     private fun deserialize(string: String): DownloadObject? {
         return try {
-            Json.decodeFromString<DownloadObject>(string)
+            json.decodeFromString<DownloadObject>(string)
         } catch (e: Exception) {
             null
         }

+ 5 - 2
app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/Anilist.kt

@@ -11,6 +11,7 @@ import kotlinx.serialization.encodeToString
 import kotlinx.serialization.json.Json
 import rx.Completable
 import rx.Observable
+import uy.kohesive.injekt.injectLazy
 
 class Anilist(private val context: Context, id: Int) : TrackService(id) {
 
@@ -34,6 +35,8 @@ class Anilist(private val context: Context, id: Int) : TrackService(id) {
 
     override val name = "AniList"
 
+    private val json: Json by injectLazy()
+
     private val interceptor by lazy { AnilistInterceptor(this, getPassword()) }
 
     private val api by lazy { AnilistApi(client, interceptor) }
@@ -196,12 +199,12 @@ class Anilist(private val context: Context, id: Int) : TrackService(id) {
     }
 
     fun saveOAuth(oAuth: OAuth?) {
-        preferences.trackToken(this).set(Json.encodeToString(oAuth))
+        preferences.trackToken(this).set(json.encodeToString(oAuth))
     }
 
     fun loadOAuth(): OAuth? {
         return try {
-            Json.decodeFromString<OAuth>(preferences.trackToken(this).get())
+            json.decodeFromString<OAuth>(preferences.trackToken(this).get())
         } catch (e: Exception) {
             null
         }

+ 7 - 4
app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/AnilistApi.kt

@@ -23,10 +23,13 @@ import okhttp3.OkHttpClient
 import okhttp3.Request
 import okhttp3.RequestBody.Companion.toRequestBody
 import rx.Observable
+import uy.kohesive.injekt.injectLazy
 import java.util.Calendar
 
 class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
 
+    private val json: Json by injectLazy()
+
     private val jsonMime = "application/json; charset=utf-8".toMediaTypeOrNull()
     private val authClient = client.newBuilder().addInterceptor(interceptor).build()
 
@@ -61,7 +64,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
                 if (responseBody.isEmpty()) {
                     throw Exception("Null Response")
                 }
-                val response = Json.decodeFromString<JsonObject>(responseBody)
+                val response = json.decodeFromString<JsonObject>(responseBody)
                 track.library_id = response["data"]!!.jsonObject["SaveMediaListEntry"]!!.jsonObject["id"]!!.jsonPrimitive.long
                 track
             }
@@ -143,7 +146,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
                 if (responseBody.isEmpty()) {
                     throw Exception("Null Response")
                 }
-                val response = Json.decodeFromString<JsonObject>(responseBody)
+                val response = json.decodeFromString<JsonObject>(responseBody)
                 val data = response["data"]!!.jsonObject
                 val page = data["Page"]!!.jsonObject
                 val media = page["media"]!!.jsonArray
@@ -203,7 +206,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
                 if (responseBody.isEmpty()) {
                     throw Exception("Null Response")
                 }
-                val response = Json.decodeFromString<JsonObject>(responseBody)
+                val response = json.decodeFromString<JsonObject>(responseBody)
                 val data = response["data"]!!.jsonObject
                 val page = data["Page"]!!.jsonObject
                 val media = page["mediaList"]!!.jsonArray
@@ -248,7 +251,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
                 if (responseBody.isEmpty()) {
                     throw Exception("Null Response")
                 }
-                val response = Json.decodeFromString<JsonObject>(responseBody)
+                val response = json.decodeFromString<JsonObject>(responseBody)
                 val data = response["data"]!!.jsonObject
                 val viewer = data["Viewer"]!!.jsonObject
                 Pair(viewer["id"]!!.jsonPrimitive.int, viewer["mediaListOptions"]!!.jsonObject["scoreFormat"]!!.jsonPrimitive.content)

+ 5 - 2
app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Bangumi.kt

@@ -11,11 +11,14 @@ import kotlinx.serialization.encodeToString
 import kotlinx.serialization.json.Json
 import rx.Completable
 import rx.Observable
+import uy.kohesive.injekt.injectLazy
 
 class Bangumi(private val context: Context, id: Int) : TrackService(id) {
 
     override val name = "Bangumi"
 
+    private val json: Json by injectLazy()
+
     private val interceptor by lazy { BangumiInterceptor(this) }
 
     private val api by lazy { BangumiApi(client, interceptor) }
@@ -111,12 +114,12 @@ class Bangumi(private val context: Context, id: Int) : TrackService(id) {
     }
 
     fun saveToken(oauth: OAuth?) {
-        preferences.trackToken(this).set(Json.encodeToString(oauth))
+        preferences.trackToken(this).set(json.encodeToString(oauth))
     }
 
     fun restoreToken(): OAuth? {
         return try {
-            Json.decodeFromString<OAuth>(preferences.trackToken(this).get())
+            json.decodeFromString<OAuth>(preferences.trackToken(this).get())
         } catch (e: Exception) {
             null
         }

+ 7 - 4
app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiApi.kt

@@ -20,10 +20,13 @@ import okhttp3.FormBody
 import okhttp3.OkHttpClient
 import okhttp3.Request
 import rx.Observable
+import uy.kohesive.injekt.injectLazy
 import java.net.URLEncoder
 
 class BangumiApi(private val client: OkHttpClient, interceptor: BangumiInterceptor) {
 
+    private val json: Json by injectLazy()
+
     private val authClient = client.newBuilder().addInterceptor(interceptor).build()
 
     fun addLibManga(track: Track): Observable<Track> {
@@ -93,7 +96,7 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
                 if (responseBody.contains("\"code\":404")) {
                     responseBody = "{\"results\":0,\"list\":[]}"
                 }
-                val response = Json.decodeFromString<JsonObject>(responseBody)["list"]?.jsonArray
+                val response = json.decodeFromString<JsonObject>(responseBody)["list"]?.jsonArray
                 response?.filter { it.jsonObject["type"]?.jsonPrimitive?.int == 1 }?.map { jsonToSearch(it.jsonObject) }
             }
     }
@@ -134,7 +137,7 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
             .map { netResponse ->
                 // get comic info
                 val responseBody = netResponse.body?.string().orEmpty()
-                jsonToTrack(Json.decodeFromString(responseBody))
+                jsonToTrack(json.decodeFromString(responseBody))
             }
     }
 
@@ -151,7 +154,7 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
             .asObservableSuccess()
             .map { netResponse ->
                 val resp = netResponse.body?.string()
-                val coll = Json { ignoreUnknownKeys = true }.decodeFromString<Collection>(resp!!)
+                val coll = json.decodeFromString<Collection>(resp!!)
                 track.status = coll.status?.id!!
                 track.last_chapter_read = coll.ep_status!!
                 track
@@ -164,7 +167,7 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
             if (responseBody.isEmpty()) {
                 throw Exception("Null Response")
             }
-            Json { ignoreUnknownKeys = true }.decodeFromString<OAuth>(responseBody)
+            json.decodeFromString<OAuth>(responseBody)
         }
     }
 

+ 4 - 1
app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiInterceptor.kt

@@ -5,9 +5,12 @@ import kotlinx.serialization.json.Json
 import okhttp3.FormBody
 import okhttp3.Interceptor
 import okhttp3.Response
+import uy.kohesive.injekt.injectLazy
 
 class BangumiInterceptor(val bangumi: Bangumi) : Interceptor {
 
+    private val json: Json by injectLazy()
+
     /**
      * OAuth object used for authenticated requests.
      */
@@ -30,7 +33,7 @@ class BangumiInterceptor(val bangumi: Bangumi) : Interceptor {
         if (currAuth.isExpired()) {
             val response = chain.proceed(BangumiApi.refreshTokenRequest(currAuth.refresh_token!!))
             if (response.isSuccessful) {
-                newAuth(Json { ignoreUnknownKeys = true }.decodeFromString<OAuth>(response.body!!.string()))
+                newAuth(json.decodeFromString<OAuth>(response.body!!.string()))
             } else {
                 response.close()
             }

+ 5 - 2
app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/Shikimori.kt

@@ -11,6 +11,7 @@ import kotlinx.serialization.encodeToString
 import kotlinx.serialization.json.Json
 import rx.Completable
 import rx.Observable
+import uy.kohesive.injekt.injectLazy
 
 class Shikimori(private val context: Context, id: Int) : TrackService(id) {
 
@@ -28,6 +29,8 @@ class Shikimori(private val context: Context, id: Int) : TrackService(id) {
 
     override val name = "Shikimori"
 
+    private val json: Json by injectLazy()
+
     private val interceptor by lazy { ShikimoriInterceptor(this) }
 
     private val api by lazy { ShikimoriApi(client, interceptor) }
@@ -116,12 +119,12 @@ class Shikimori(private val context: Context, id: Int) : TrackService(id) {
     }
 
     fun saveToken(oauth: OAuth?) {
-        preferences.trackToken(this).set(Json.encodeToString(oauth))
+        preferences.trackToken(this).set(json.encodeToString(oauth))
     }
 
     fun restoreToken(): OAuth? {
         return try {
-            Json.decodeFromString<OAuth>(preferences.trackToken(this).get())
+            json.decodeFromString<OAuth>(preferences.trackToken(this).get())
         } catch (e: Exception) {
             null
         }

+ 8 - 5
app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriApi.kt

@@ -24,9 +24,12 @@ import okhttp3.OkHttpClient
 import okhttp3.Request
 import okhttp3.RequestBody.Companion.toRequestBody
 import rx.Observable
+import uy.kohesive.injekt.injectLazy
 
 class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInterceptor) {
 
+    private val json: Json by injectLazy()
+
     private val jsonime = "application/json; charset=utf-8".toMediaTypeOrNull()
     private val authClient = client.newBuilder().addInterceptor(interceptor).build()
 
@@ -72,7 +75,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
                 if (responseBody.isEmpty()) {
                     throw Exception("Null Response")
                 }
-                val response = Json.decodeFromString<JsonArray>(responseBody)
+                val response = json.decodeFromString<JsonArray>(responseBody)
                 response.map { jsonToSearch(it.jsonObject) }
             }
     }
@@ -125,7 +128,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
             .asObservableSuccess()
             .map { netResponse ->
                 val responseBody = netResponse.body?.string().orEmpty()
-                Json.decodeFromString<JsonObject>(responseBody)
+                json.decodeFromString<JsonObject>(responseBody)
             }.flatMap { mangas ->
                 authClient.newCall(request)
                     .asObservableSuccess()
@@ -134,7 +137,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
                         if (responseBody.isEmpty()) {
                             throw Exception("Null Response")
                         }
-                        val response = Json.decodeFromString<JsonArray>(responseBody)
+                        val response = json.decodeFromString<JsonArray>(responseBody)
                         if (response.size > 1) {
                             throw Exception("Too much mangas in response")
                         }
@@ -148,7 +151,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
 
     fun getCurrentUser(): Int {
         val user = authClient.newCall(GET("$apiUrl/users/whoami")).execute().body?.string()!!
-        return Json.decodeFromString<JsonObject>(user)["id"]!!.jsonPrimitive.int
+        return json.decodeFromString<JsonObject>(user)["id"]!!.jsonPrimitive.int
     }
 
     fun accessToken(code: String): Observable<OAuth> {
@@ -157,7 +160,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
             if (responseBody.isEmpty()) {
                 throw Exception("Null Response")
             }
-            Json { ignoreUnknownKeys = true }.decodeFromString<OAuth>(responseBody)
+            json.decodeFromString<OAuth>(responseBody)
         }
     }
 

+ 4 - 1
app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriInterceptor.kt

@@ -4,9 +4,12 @@ import kotlinx.serialization.decodeFromString
 import kotlinx.serialization.json.Json
 import okhttp3.Interceptor
 import okhttp3.Response
+import uy.kohesive.injekt.injectLazy
 
 class ShikimoriInterceptor(val shikimori: Shikimori) : Interceptor {
 
+    private val json: Json by injectLazy()
+
     /**
      * OAuth object used for authenticated requests.
      */
@@ -23,7 +26,7 @@ class ShikimoriInterceptor(val shikimori: Shikimori) : Interceptor {
         if (currAuth.isExpired()) {
             val response = chain.proceed(ShikimoriApi.refreshTokenRequest(refreshToken))
             if (response.isSuccessful) {
-                newAuth(Json.decodeFromString<OAuth>(response.body!!.string()))
+                newAuth(json.decodeFromString<OAuth>(response.body!!.string()))
             } else {
                 response.close()
             }