Skip to content

Commit

Permalink
[代码修改] Json 解析工具修改为 kotlinx
Browse files Browse the repository at this point in the history
  • Loading branch information
jiewang41 committed Jan 5, 2021
1 parent 2af068b commit 9820766
Show file tree
Hide file tree
Showing 16 changed files with 191 additions and 27 deletions.
9 changes: 5 additions & 4 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ plugins {
id("com.android.application")
kotlin("android")
kotlin("kapt")
kotlin("plugin.serialization") version Configuration.Versions.kotlin_version
id("kotlin-parcelize")
}

Expand Down Expand Up @@ -142,9 +143,6 @@ android {
isAbortOnError = false
}

// 使用 httpclient
useLibrary("org.apache.http.legacy")

// 配置 APK 输出路径
applicationVariants.all {
outputs.all {
Expand All @@ -163,6 +161,7 @@ android {
// kotlin Jvm 版本
kotlinOptions {
jvmTarget = "1.8"
freeCompilerArgs += arrayOf("-Xopt-in=kotlinx.serialization.ExperimentalSerializationApi")
}
}

Expand All @@ -172,6 +171,8 @@ dependencies {
implementation(Configuration.Dependencies.kotlin_stdlib)
// 协程
implementation(Configuration.Dependencies.kotlin_coroutines)
// Json 序列化
implementation(Configuration.Dependencies.kotlin_serialization)

// Dex 分包
implementation(Configuration.Dependencies.androidx_multidex)
Expand Down Expand Up @@ -222,7 +223,7 @@ dependencies {

// Retrofit
implementation(Configuration.Dependencies.retrofit)
implementation(Configuration.Dependencies.retrofit_gson)
implementation(Configuration.Dependencies.retrofit_converter_kt)

// Glide
implementation(Configuration.Dependencies.coil)
Expand Down
23 changes: 22 additions & 1 deletion app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -188,4 +188,25 @@

# lib_recyclerview
-keep class cn.wj.android.recyclerview.** { *; }
-keep class * extends cn.wj.android.recyclerview.** { *; }
-keep class * extends cn.wj.android.recyclerview.** { *; }

# kotlin serialization
-keepattributes *Annotation*, InnerClasses
-dontnote kotlinx.serialization.AnnotationsKt # core serialization annotations

# kotlinx-serialization-json specific. Add this if you have java.lang.NoClassDefFoundError kotlinx.serialization.json.JsonObjectSerializer
-keepclassmembers class kotlinx.serialization.json.** {
*** Companion;
}
-keepclasseswithmembers class kotlinx.serialization.json.** {
kotlinx.serialization.KSerializer serializer(...);
}

# Change here com.yourcompany.yourpackage
-keep,includedescriptorclasses class com.wj.sampleproject.**$$serializer { *; } # <-- change package name to your app's
-keepclassmembers class com.yourcompany.yourpackage.** { # <-- change package name to your app's
*** Companion;
}
-keepclasseswithmembers class com.wj.sampleproject.** { # <-- change package name to your app's
kotlinx.serialization.KSerializer serializer(...);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.wj.sampleproject.di

import cn.wj.android.common.ext.orEmpty
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
import com.orhanobut.logger.Logger
import com.tencent.mmkv.MMKV
import com.wj.android.okhttp.InterceptorLogger
Expand All @@ -11,6 +12,7 @@ import com.wj.sampleproject.adapter.NavigationRvAdapter
import com.wj.sampleproject.adapter.SystemCategoryRvAdapter
import com.wj.sampleproject.constants.SP_KEY_COOKIES
import com.wj.sampleproject.entity.CookieEntity
import com.wj.sampleproject.ext.jsonDefault
import com.wj.sampleproject.ext.toJsonString
import com.wj.sampleproject.ext.toTypeEntity
import com.wj.sampleproject.net.UrlDefinition
Expand All @@ -21,12 +23,12 @@ import com.wj.sampleproject.viewmodel.*
import okhttp3.Cookie
import okhttp3.CookieJar
import okhttp3.HttpUrl
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.core.module.Module
import org.koin.dsl.module
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory

/** 网络请求 Module */
val netModule: Module = module {
Expand Down Expand Up @@ -69,7 +71,7 @@ val netModule: Module = module {
single<Retrofit> {
Retrofit.Builder()
.baseUrl(UrlDefinition.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addConverterFactory(jsonDefault.asConverterFactory("application/json; charset=UTF-8".toMediaType()))
.client(get())
.build()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import cn.wj.android.common.ext.isNotNullAndBlank
import cn.wj.android.common.ext.isNotNullAndEmpty
import cn.wj.android.common.ext.orFalse
import com.wj.sampleproject.constants.STR_TRUE
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient

/**
* 首页文章列表数据实体类
Expand All @@ -17,6 +19,7 @@ import com.wj.sampleproject.constants.STR_TRUE
* @param over 是否结束
* @param datas 文章数据W
*/
@Serializable
data class ArticleListEntity(
val curPage: String? = "",
val offset: String? = "",
Expand Down Expand Up @@ -57,6 +60,7 @@ data class ArticleListEntity(
* @param zan 赞 数量
* @param top 自设属性 是否置顶
*/
@Serializable
data class ArticleEntity(
val apkLink: String? = "",
val author: String? = "",
Expand Down Expand Up @@ -98,6 +102,7 @@ data class ArticleEntity(
get() = tags.isNotNullAndEmpty()

/** 标记 - 是否收藏 */
@Transient
val collected: ObservableBoolean = ObservableBoolean(false)

/** 标记 - 是否显示封面 */
Expand All @@ -111,6 +116,7 @@ data class ArticleEntity(
* @param name 标签名
* @param url 标签地址
*/
@Serializable
data class ArticleTagEntity(
val name: String? = "",
val url: String? = ""
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.wj.sampleproject.entity

import kotlinx.serialization.Serializable

/**
* 首页 Banner 数据实体类
*
Expand All @@ -12,6 +14,7 @@ package com.wj.sampleproject.entity
* @param type ?
* @param url 跳转链接
*/
@Serializable
data class BannerEntity(
val desc: String? = "",
val id: String? = "",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.wj.sampleproject.entity

import android.os.Parcelable
import kotlinx.parcelize.Parcelize
import kotlinx.serialization.Serializable

/**
* 公众号、项目分类数据实体类
Expand All @@ -10,6 +11,7 @@ import kotlinx.parcelize.Parcelize
* @param name 分类名称
*/
@Parcelize
@Serializable
data class CategoryEntity(
val id: String? = "",
val name: String? = ""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.wj.sampleproject.entity

import android.os.Parcelable
import kotlinx.parcelize.Parcelize
import kotlinx.serialization.Serializable

/**
* 收藏网站数据实体类
Expand All @@ -20,6 +21,7 @@ import kotlinx.parcelize.Parcelize
* @author 王杰
*/
@Parcelize
@Serializable
data class CollectedWebEntity(
val desc: String? = "",
val icon: String? = "",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
@file:UseContextualSerialization(forClasses = [Cookie::class])

package com.wj.sampleproject.entity

import kotlinx.serialization.Serializable
import kotlinx.serialization.UseContextualSerialization
import okhttp3.Cookie

/**
Expand All @@ -11,6 +15,7 @@ import okhttp3.Cookie
*
* @author 王杰
*/
@Serializable
data class CookieEntity(
val cookies: ArrayList<Cookie>? = arrayListOf()
)
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.wj.sampleproject.entity

import kotlinx.serialization.Serializable

/**
* 热门搜索数据实体类
*
Expand All @@ -9,6 +11,7 @@ package com.wj.sampleproject.entity
*
* @author 王杰
*/
@Serializable
data class HotSearchEntity(
val id: String? = "",
val link: String? = "",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package com.wj.sampleproject.entity

import kotlinx.serialization.Serializable

/**
* 导航列表数据实体类
*
* @param cid 导航 id
* @param name 分类名
* @param articles 导航列表
*/
@Serializable
data class NavigationListEntity(
val cid: String? = "",
val name: String? = "",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.wj.sampleproject.entity

import kotlinx.serialization.Serializable

/**
* 体系目录数据实体类
*
Expand All @@ -11,6 +13,7 @@ package com.wj.sampleproject.entity
* @param visible ?
* @param children 子目录列表
*/
@Serializable
data class SystemCategoryEntity(
val courseId: String? = "",
val id: String? = "",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.wj.sampleproject.entity

import kotlinx.serialization.Serializable

/**
* 用户信息数据实体类
*
Expand All @@ -20,10 +22,11 @@ package com.wj.sampleproject.entity
*
* @author 王杰
*/
@Serializable
data class UserInfoEntity(
val admin: String? = "",
val chapterTops: ArrayList<Any>? = arrayListOf(),
val collectIds: ArrayList<Any>? = arrayListOf(),
// val chapterTops: ArrayList<Any>? = arrayListOf(),
// val collectIds: ArrayList<Any>? = arrayListOf(),
val email: String? = "",
val icon: String? = "",
val id: String? = "",
Expand Down
66 changes: 50 additions & 16 deletions app/src/main/kotlin/com/wj/sampleproject/ext/Transform.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
@file:Suppress("unused")

package com.wj.sampleproject.ext

import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.orhanobut.logger.Logger
import com.wj.sampleproject.constants.NET_RESPONSE_CODE_ERROR
import com.wj.sampleproject.model.SnackbarModel
import com.wj.sampleproject.net.NetResult
import com.wj.sampleproject.serializer.CookieKSerializer
import kotlinx.serialization.DeserializationStrategy
import kotlinx.serialization.SerializationStrategy
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import kotlinx.serialization.modules.SerializersModule
import okhttp3.Cookie
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.toRequestBody
Expand All @@ -19,28 +26,55 @@ import org.json.JSONObject
* @author 王杰
*/

/** 默认 [Json] 解析 */
val jsonDefault = Json {
// 是否编码默认值
encodeDefaults = true
// 忽略未知 key 不抛出异常
ignoreUnknownKeys = true
// 是否使用宽松模式
isLenient = true
// 是否允许将 key-value 转换为 数组
allowStructuredMapKeys = false
// 是否对打印的 json 格式化
prettyPrint = true
// 指定打印缩进字符串
// prettyPrintIndent = " "
// 非空类型为空或找不到对应枚举时使用默认值
coerceInputValues = false
// 将多态序列化为默认数组格式
useArrayPolymorphism = false
// 多态序列化的类描述符属性的名称
// classDiscriminator = "type"
// 是否取消对特殊浮点值的规范
allowSpecialFloatingPointValues = false
// 指定序列化模块
serializersModule = SerializersModule {
contextual(Cookie::class, CookieKSerializer)
}
}

/**
* 将 [String] 转换为 [T] 类型数据对象并返回,可传参数 [gson]
* 使用 [json] 以及 [deserializer] 将 [String] 解析为 [T] 数据实体
* > 转换失败返回 `null`
*/
inline fun <reified T> String?.toTypeEntity(gson: Gson = Gson()): T? {
return try {
gson.fromJson(this, object : TypeToken<T>() {}.type)
} catch (e: Exception) {
Logger.t("JSON").e(e, "toBean")
null
inline fun <reified T> String?.toTypeEntity(json: Json = jsonDefault, deserializer: DeserializationStrategy<T>? = null): T? {
return when {
this.isNullOrBlank() -> null
null != deserializer -> json.decodeFromString(deserializer, this)
else -> json.decodeFromString(this)
}
}

/**
* 将 [T] 对象转换为 [String] 并返回,可传参数 [gson]
* 使用 [json] 以及 [serializer] 将数据实体 [T] 转换为 [String]
* > 转换失败返回 `""`
*/
inline fun <reified T> T?.toJsonString(gson: Gson = Gson()): String {
return try {
gson.toJson(this, object : TypeToken<T>() {}.type)
} catch (e: Exception) {
""
inline fun <reified T> T?.toJsonString(json: Json = jsonDefault, serializer: SerializationStrategy<T>? = null): String {
return when {
null == this -> ""
null != serializer -> json.encodeToString(serializer, this)
else -> json.encodeToString(this)
}
}

Expand Down
2 changes: 2 additions & 0 deletions app/src/main/kotlin/com/wj/sampleproject/net/NetResult.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.wj.sampleproject.net

import com.wj.sampleproject.constants.NET_RESPONSE_CODE_FAILED
import kotlinx.serialization.Serializable

/**
* 网络请求返回数据基本框架
Expand All @@ -9,6 +10,7 @@ import com.wj.sampleproject.constants.NET_RESPONSE_CODE_FAILED
* @param errorMsg 返回信息
* @param data 请求返回数据
*/
@Serializable
data class NetResult<T>(
val errorCode: Int = NET_RESPONSE_CODE_FAILED,
val errorMsg: String? = "",
Expand Down
Loading

0 comments on commit 9820766

Please sign in to comment.