简体   繁体   中英

Why the Json.decodeFromString does not work in the Release version on android app

I am receiving a response from the server as json and want to convert it to an array using kotlinx.serialization.json.Json.decodeFromString. The code works fine in the Debag version, but it crashes in the Release version. Help, please, what am I doing wrong?

My code in class ActivityPro

@Serializable
data class PaymentResult(val id: String, val data: String)

@Serializable
data class PaymentRequest(val result: PaymentResult, val errorCode: Int, val errorMessage: String)

...
val paymentRequest = Json.decodeFromString<PaymentRequest>(responseString)
                    

responseString

{"result":{"id":"2ad333b0-000f-5000-8000-1ec5665f4757","data":"https:\/\/3ds-gate.yoomoney.ru\/card-auth?acsUri=https%3A%2F%2F3ds-ds2.mirconnect.ru%3A443%2Fsc1%2Fpareq&MD=4399694261676&PaReq=eJxVUU1zgjAQ%2FSuOxx5ICKQaZ82MlkM9xFFrDz1mwo4yKmCAov76Jgq1PWXf24%2B8fQvbvUVMPtA0FiUorCq9w0GWToerzZpFPKKh4GIoYTXb4FnCN9oqK3IZBjRgQHroOq3Z67yWoM15vlhKHlIaj4B0EE5oF4kUTPB4zFhIgTwYyPUJ5Zd6KY%2F6CuSOwBRNXturfI0jID2Axh7lvq7LakLItSgO2okNbAPEJ4A8JawaH1Vu0CVLpUpm7fK2aJdbw1SiWnVbc3U7tGq7mwLxFZDqGiWjXhcdD%2BhoQumEhkDuPOiTVyA3n%2FOBoAF10jsGSv%2FR7AEE9Zm%2FDDhTLeam36NHgJeyyNFVOAd%2FY0ixMm6N7nnu8PbuTTW1MysecR7FXIjIG3un%2FLDMucPi8DHNAyC%2BiXQ3I91ZXfTv3D8Xnqa1&TermUrl=https%3A%2F%2Fpaymentcard.yoomoney.ru%3A443%2F3ds%2Fchallenge%2F279%2FsU5z3DrCkvZJlGEBl2rAYmgE45QZ..001.202210"},"errorCode":0,"errorMessage":""}

error log

2022-10-08 10:35:08.894 27772-27772/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: ru.keytomyself.customeraccounting, PID: 27772
jb.p0: Unresolved class: class ru.keytomyself.customeraccounting.ActivityPro$a
    at jb.l$a$i.invoke(SourceFile:32)
    at jb.r0$a.invoke(SourceFile:2)
    at jb.l$a.a(SourceFile:1)
    at jb.l.C(Unknown Source:8)
    at jb.l.getDescriptor(Unknown Source:0)
    at jb.s0.i(SourceFile:1)
    at ab.c0.d(Unknown Source:10)
    at ze.a0$b.invokeSuspend(SourceFile:2)
    at ta.a.resumeWith(Unknown Source:8)
    at pd.o0.run(Unknown Source:86)
    at android.os.Handler.handleCallback(Handler.java:938)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:236)
    at android.app.ActivityThread.main(ActivityThread.java:8057)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:620)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1011)

I will be grateful for any help

The most likely cause of this is that you have enabled code minification/obfuscation for your release build in your build.gradle . After obfuscation your class will be looking something like this:

@Serializable
data class ABC(val z: String, val zz: String) // PaymentResult class

Now if your try to decode the string {"id":"2ad333b0", "data": "https:"} into this data class, it will fail because the class has no id property, it has been renamed to z .

To prevent this from happening, one solution is to add @SerialName annotation to all the fields in your serializable classes. For example,

@Serializable
data class PaymentResult(
    @SerialName("id")
    val id: String,
    @SerialName("data") 
    val data: String
)

Now instead of using property name, the library will now use the provided SerialName while decoding the json and these strings aren't obfuscated.

Another solution is to disable obfuscation for these serializable classes. You can use the @Keep annotation to exclude a particular class/function from being obfuscated/minified.

@Keep
@Serializable
data class PaymentResult(val id: String, val data: String)

@Keep
@Serializable
data class PaymentRequest(val result: PaymentResult, val errorCode: Int, val errorMessage: String)

The other way is to add rules to proguard-rules.pro file to exclude certain classes/directories from being obfuscated. Checkout the following resources on how to write those rules:

https://www.guardsquare.com/manual/configuration/usage#keepoptions

How to keep/exclude a particular package path when using proguard?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM