NotSerializableException: kotlin.UNINITIALIZED_VALUE 设置 minifyEnabled 后为 true

Posted

技术标签:

【中文标题】NotSerializableException: kotlin.UNINITIALIZED_VALUE 设置 minifyEnabled 后为 true【英文标题】:NotSerializableException: kotlin.UNINITIALIZED_VALUE after setting minifyEnabled true 【发布时间】:2020-12-09 19:34:33 【问题描述】:

在应用程序build.gradle 脚本中设置minifyEnabled true 后,我开始收到此异常:

Caused by: java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = some.package.SomeClass)
    at android.os.Parcel.writeSerializable(Parcel.java:1767)
    …
Caused by: java.io.NotSerializableException: kotlin.UNINITIALIZED_VALUE

当我尝试将class SomeClass : Parcelable 传递给另一个活动时发生崩溃。

我尝试使用-keep class some.package.**.* *; 将所有应用类列入白名单,但没有成功。

【问题讨论】:

【参考方案1】:

我偶然发现了同样的问题,目前的答案是错误的:在惰性上添加 @delegate:Transient 将使反序列化的支持字段无效。

由于该问题仅在 minifyEnabled = true 时出现,因此这是 Proguard/R8 问题。我通过在我的proguard-rules.pro 中添加以下几行来解决它:

-keep class * implements kotlin.Lazy 
    *;

【讨论】:

很高兴我找到了你的答案。我遇到了完全相同的 R8 问题,这解决了问题。【参考方案2】:

惰性代理在幕后使用UNINITIALIZED_VALUE 对象。它用于检查变量是否被声明。以某种方式 [需要更多信息] 懒惰的委托在代码缩小期间改变了他们的行为。它会造成这样的情况,只要禁用minifyEnabled,然后传递具有惰性初始化字段的对象就可以正常工作,而无需尝试对其进行序列化。但是启用 minify 后,Java 会尝试序列化 UNINITIALIZED_VALUE,这会在运行时引发异常。

不幸的是,stacktrace 并没有准确地告诉您必须更新哪个类中的哪个字段。至少它会告诉您哪个主类包含您损坏的Serializable 类。

假设在这种情况下some.package.SomeClass 包含AnotherClass 字段。要修复它,您需要找到类实现Serializable 的所有惰性类字段。然后将@delegate:Transient 添加到它们,例如。

class AnotherClass: Serializable 

    …

    @delegate:Transient // <- add this
    val myLazyField by lazy  "Kotlin, why?!" 

【讨论】:

错了:添加@delegate:Transient 将使支持字段无效,并且在访问它时会抛出NPE。

以上是关于NotSerializableException: kotlin.UNINITIALIZED_VALUE 设置 minifyEnabled 后为 true的主要内容,如果未能解决你的问题,请参考以下文章

Spark 中的 NotSerializableException

因为代理原因导致的NotSerializableException

未知类的 java.io.NotSerializableException

java.io.NotSerializableException:异常

NotSerializableException 类,但我的项目中没有 Item 类?

Storm java.io.NotSerializableException:运行拓扑时