Proguard删除成员字段初始化

时间:2015-09-15 21:13:08

标签: android proguard

My Proguard发布版本正在删除我的成员字段的初始化值。这导致我的默认值丢失,导致我的调试和发布版本之间的行为不同。我该如何阻止这种情况发生?

这是我的源代码

public class MyClass implements Serializable {
    private static final long serialVersionUID = 1L;

    @SerializedName("myField")
    private boolean myFieldEnabled = true;

    public boolean isMyFieldEnabled() {
        return myFieldEnabled;
    }

    public void setMyFieldEnabled(boolean myFieldEnabled) {
        this.myFieldEnabled = myFieldEnabled;
    }

    ...

模糊处理的代码如下所示(删除了setter和getter):

public final class ai implements Serializable
{
    private static final long serialVersionUID = 1L;
    @z(x="myField")
    public boolean myFieldEnabled;

这是我build.gradle的一个片段:

release {
    minifyEnabled true
    shrinkResources false
    proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'custom-proguard-rules-optimize.pro'
}

以下是我的自定义规则中的关键Proguard优化规则(来自custom-proguard-rules-optimize.pro):

# Disable the "code/allocation/variable" optimizations to workaround a
# Proguard bug.  Source: http://stackoverflow.com/a/7587680/112705
-optimizations !code/simplification/arithmetic,field/removal/writeonly,!class/merging/*,!code/allocation/variable
-allowaccessmodification

以下是我们使用的Android默认规则中的关键Proguard优化规则(来自proguard-android-optimize.txt):

-optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*
-optimizationpasses 5

我检查了the Proguard optimizations documentation,但我看不到涵盖此内容的优化或混淆选项。

更新

  • 在我们的优化中添加!field/*没有帮助 - 该字段似乎仍未初始化。希望这个优化已经从Android默认的Proguard规则中获取......
  • 删除field/removal/writeonly没有帮助。
  • 添加!code/simplification/field没有帮助。

2 个答案:

答案 0 :(得分:1)

我试图混淆一个可序列化的课程,但我没有得到你的问题。我使用了默认的proguard-android-optimize.txt和你的优化版本,一切都很好。

原创课程

public class TestSerializable implements Serializable {
    private static final long serialVersionUID = 1L;

    @SerializedName("myField")
    private boolean myFieldEnabled = true;

    public boolean isMyFieldEnabled() {
        return myFieldEnabled;
    }

    public void setMyFieldEnabled(boolean myFieldEnabled) {
        this.myFieldEnabled = myFieldEnabled;
    }
}

在proguard之后

public final class p implements Serializable
{
    @c(a="myField")
    private boolean a = true;

    public final boolean a()
    {
        return this.a;
    }

    public final void b()
    {
        this.a = false;
    }
}

我有三个建议

  • 尝试将-keep class * implements java.io.Serializable添加到您的proguard文件中,看看会发生什么
  • 在您的代码中验证每个setMyFieldEnabled(false)之后没有调用方法new MyClass,否则优化可以决定删除默认值
  • 查看混淆的序列化类:字段myFieldEnabled是公共的;所以它可以从任何地方访问。如果proguard用类似于ai a = new ai(); ai.myFieldEnabled = true;
  • 的代码替换代码,请检查使用MyClass的混淆类

答案 1 :(得分:0)

尝试声明实现Serializable

的类的默认构造函数
public class MyClass implements Serializable {
    private static final long serialVersionUID = 1L;

    @SerializedName("myField")
    private boolean myFieldEnabled;

    private MyClass() {
        myFieldEnabled = true; 
    }  

    public boolean isMyFieldEnabled() {
        return myFieldEnabled;
    }

    public void setMyFieldEnabled(boolean myFieldEnabled) {
        this.myFieldEnabled = myFieldEnabled;
    }

对于具有serailisable的默认ProGaurd配置,请参阅 http://proguard.sourceforge.net/manual/examples.html#serializable