返回

在混淆代码时如何保留密闭类的构造函数?

Android

如何在混淆代码时保留密闭类的构造函数

引言

当启用混淆时,密闭类的构造函数可能会被移除,从而导致无法实例化这些类。本文将指导你使用 Proguard 规则来解决此问题,确保在混淆后保留密闭类的构造函数。

问题:构造函数的意外移除

混淆是一个代码优化过程,可以移除未使用的代码和数据。当启用混淆时,编译器可能会错误地将密闭类的构造函数视为未使用的代码,从而将其移除。

解决方案:使用 Proguard 规则

为了防止构造函数被移除,可以使用 Proguard 规则来显式保留它们。Proguard 是一种广泛用于 Android 项目的混淆工具,可以通过向 proguard-rules.pro 文件中添加规则来定制混淆行为。

步骤:添加 Proguard 规则

要保留密闭类的构造函数,请在 proguard-rules.pro 文件中添加以下规则:

-keepclassmembers class * extends android.support.annotation.Keep {
    public <init>(...);
}

此规则指示 Proguard 保留所有扩展 android.support.annotation.Keep 注解的类的所有公共构造函数,无论参数如何。

启用 Proguard

确保在 Gradle 脚本中启用了 Proguard:

buildTypes {
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}

重新构建项目

重新构建项目以应用 Proguard 规则。

示例:密闭类的保留

例如,假设有一个密闭类 MySealedClass,它有以下构造函数:

public class MySealedClass {
    public MySealedClass() { }
    public MySealedClass(int value) { }
}

通过添加上述 Proguard 规则,你可以确保这两个构造函数在混淆后仍然存在。

常见问题解答

1. Proguard 规则的范围是什么?

Proguard 规则仅适用于扩展 android.support.annotation.Keep 注解的类。

2. 除了密闭类,还能保留哪些类的构造函数?

此规则可以保留任何扩展 android.support.annotation.Keep 注解的类的构造函数。

3. 如果我不想使用 android.support.annotation.Keep 注解怎么办?

你可以使用其他注解,例如 @Keep@Retention(RetentionPolicy.RUNTIME)

4. 为什么需要使用 ... 而不是具体的参数列表?

... 表示保留所有参数的构造函数,无论参数如何。

5. Proguard 规则是否影响性能?

Proguard 规则对性能几乎没有影响。

结论

使用 Proguard 规则保留密闭类的构造函数是一个简单而有效的解决方法。通过遵循本指南,你可以确保即使在启用混淆的情况下,密闭类的构造函数仍然可用于实例化这些类。