我几天来一直在努力尝试让 ProGuard/R8 缩小而不破坏我的构建,而且我似乎无法在网上找到有关这个最新问题的任何信息:在我的调试构建中,
rememberSaveable
能够记住可组合项的创建/销毁/重组之间的一些关键状态。在 proguard 设置中使用 -dontshrink
的发布版本也可以正常工作。但是,当我构建完全启用缩小功能的发布版本时,可组合项突然在重新创建之间完全忘记了其状态。是否有一条规则可以用来告诉 ProGuard 停止执行任何缩小或树抖动导致的操作?这是我的代码的样子:
fun ServerChannelNav(
...
startingServerId: String = "",
...
lastServerChannels: Map<String, String>,
...
) {
var currentServerId by rememberSaveable { mutableStateOf(startingServerId) }
var currentChannelId by rememberSaveable {
mutableStateOf(
lastServerChannels[startingServerId] ?: ""
)
}
...
}
这是到目前为止我的 proguard 规则:
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
-dontobfuscate
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
-dontwarn kotlin.reflect.jvm.internal.**
-keep class kotlin.reflect.jvm.internal.** { *; }
-keep interface javax.annotation.Nullable
-keepattributes SourceFile,LineNumberTable,*Annotation*,EnclosingMethod,Signature,Exceptions,InnerClasses
-keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation
-dontwarn okhttp3.**
-dontwarn okio.**
-dontwarn javax.annotation.**
-keepclasseswithmembers class * {
@retrofit2.http.* <methods>;
}
-keep,allowobfuscation,allowshrinking class retrofit2.Response
-keep class kotlin.Metadata { *; }
-keep class kotlin.reflect.** { *; }
-keep,allowshrinking class io.github.alexispurslane.bloc.data.SinglePolyUnwrappedDeserializer { *; }
-keep,allowshrinking class io.github.alexispurslane.bloc.data.SinglePolyUnwrappedDeserializer$** { *; }
-keepclassmembers class io.github.alexispurslane.bloc.data.** {
@com.fasterxml.jackson.annotation.JsonCreator *;
@com.fasterxml.jackson.annotation.JsonProperty *;
** serialize*(...);
** deserialize*(...);
}
-keep class io.github.alexispurslane.bloc.data.network.models.** {
@com.fasterxml.jackson.annotation.** *;
*;
}
-keep class io.github.alexispurslane.bloc.data.network.models.RevoltWebSocketRequest$** {
@com.fasterxml.jackson.annotation.** *;
*;
}
-keep class io.github.alexispurslane.bloc.data.network.models.RevoltWebSocketResponse$** {
@com.fasterxml.jackson.annotation.** *;
*;
}
-keep class com.fasterxml.jackson.** {
*;
}
-dontwarn com.fasterxml.jackson.databind.**
-keep class * implements java.io.Serializable
-keep interface com.fasterxml.jackson.** { *; }
-keep class com.fasterxml.** { *; }
-dontwarn com.fasterxml.jackson.databind.**
-keep @com.fasterxml.jackson.annotation.JsonIgnoreProperties class * { *; }
-keep class com.fasterxml.jackson.annotation.** {
*;
}
-keep class androidx.datastore.*.** {*;}
我可以关闭树摇动和缩小功能,但这会使我的应用程序大小增加一倍(80MB),这对于我的应用程序实际上有多小来说似乎有点沉重。
事实证明,发生的事情并不是
rememberSaveable
不起作用,而是在创建/销毁之间支持它的东西——首选数据存储——不起作用,因为 rememberSaveable
不应该是 在创造/毁灭之间持续。首选项数据存储不起作用的原因是什么?
ProGuard 再一次打破了 Jackson 序列化/反序列化!在本例中,我使用
TypeReference
的 Kotlin 匿名子类对象(例如 object : TypeReference<T> {}
)将一些类型信息传递到 Jackson 序列化操作中,因为很难为此类内容编写规则(与顶级声明不同)类型信息被剥离,序列化在幕后崩溃。所以我只需要在文字之前添加一个 @Keep
注释就可以了。