如何阻止ProGuard从类中剥离Serializable接口

kab*_*uko 9 java android proguard serializable

是否有一种明确的方法可以阻止ProGuard将类更改为实现接口?

我有一个实现的类java.io.Serializable,让我们称之为com.my.package.name.Foo.我发现在运行ProGuard后,它不再实现了Serializable.我得到null我从投后Serializable,以Foofalse,如果我请与一个实例instanceof Serializable.我已确保将ProGuard设置为忽略此类:

-keep class com.my.package.name.Foo
Run Code Online (Sandbox Code Playgroud)

我也尝试过:

-keep class com.my.package.name.Foo { *; }
Run Code Online (Sandbox Code Playgroud)

我也尝试了整个包:

-keep class com.my.package.name.** { *; }
Run Code Online (Sandbox Code Playgroud)

要么:

-keep class com.my.package.** { *; }
Run Code Online (Sandbox Code Playgroud)

并且还要保留所有Serializable课程:

-keep class * implements java.io.Serializable { *; }
Run Code Online (Sandbox Code Playgroud)

但无济于事.我在兄弟包(大致:)中有另一个类,com.my.package.name2.Bar它也实现Serializable和使用类似但没有问题.

我不确定它是否相关,但我将它装在一个罐子里用于Android.使用这些类的代码包括将它们放入Bundles中,这就是我需要的原因Serializable.我认为也许某种程度上ProGuard认为它Foo从未被用作a Serializable但似乎不太可能,因为我将它作为参数传递给我,Bundle.putSerializable(String, Serializable)并且我做了隐式演员:Serializable serializable = foo;.事实上,当我调试时,我可以看到Fooget into Bundle,我可以检查Bundle并查看Foo那里的实例,但是当检索它时,转换失败.

Sab*_*med 29

我使用下面的配置修复了同样的问题.

-keepnames class * implements java.io.Serializable
-keepclassmembers class * implements java.io.Serializable {
    static final long serialVersionUID;
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    !static !transient <fields>;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}
Run Code Online (Sandbox Code Playgroud)

官方文档 http://proguard.sourceforge.net/manual/examples.html#serializable

  • 在我看来,这应该是proguard中的默认规则. (4认同)
  • 文档:http://proguard.sourceforge.net/manual/examples.html#serializable (2认同)

Eri*_*une 5

ProGuard 永远不会从处理的代码中的类(如 Foo)中剥离库中定义的接口(如 Serializable)。库代码可能会转换到这些接口,因此无法删除它们。

我从 Serializable 转换为 Foo 后得到 null

这意味着该实例必须为空才能开始。如果您得到 ClassCastException,您的分析将是正确的。您可以检查 Foo 是否仍然使用 Serializable 实现javap。问题可能出在其他地方。有关序列化的提示,您可以查看 ProGuard 手册 > 示例 >处理可序列化类

更新:

在这种情况下,结果证明是配置问题。ProGuard 只能处理类文件,前提是它知道有关其层次结构的所有信息(就像编译器一样)。您确实必须指定运行时类:

-libraryjars <java.home>/lib/rt.jar
Run Code Online (Sandbox Code Playgroud)

或安卓:

-libraryjars /usr/local/android-sdk/platforms/android-17/android.jar
Run Code Online (Sandbox Code Playgroud)

Android Ant/Eclipse 构建会自动为您指定所有必要的 -injars/-outjars/-libraryjars 选项,但在自定义构建过程中,您必须自己指定它们。参考文献 ProGuard 手册 > 示例 >一个完整的 Android 应用程序

请注意,选项 -dontwarn 会使警告消失,但不会使问题消失。仅在确实需要时才使用它。