【问题标题】:Why Proguard keeps Activity class in Android?为什么 Proguard 在 Android 中保留 Activity 类?
【发布时间】:2013-12-16 20:09:27
【问题描述】:

我已将 ProGuard 应用到我的 Android 应用程序。

我正在使用

android-studio/sdk/tools/proguard/proguard-android.txt

作为配置文件,什么都不做。

在这个文件中,我可以看到关于Activity的唯一声明:

We want to keep methods in Activity that could be used in the XML attribute onClick
-keepclassmembers class * extends android.app.Activity {
   public void *(android.view.View);
}

由此可见,Activity 类名被 ProGuard 混淆了,而一些方法保持原样。这是可以理解的。

但是,在我的应用程序中,我使用字符串从字符串创建一个 Activity 类

Class.forName("my.app.MyActivity")

然后我启动这个 Activity,它开始正常。

但这意味着 Activity 派生的类没有被混淆??。它应该失败了,因为 ProGuard 没有 Activity-keep class 指令,它只有 -keepclassmembers.

如果我可以依赖我观察到的行为,请有人解释一下吗?还是我误解了-keepclassmembers 指令?

【问题讨论】:

  • 您应该发布整个文件,因为仅此行不足以解释为什么它保留 Activity 名称

标签: android proguard


【解决方案1】:

因为清单中列出了活动,并且其中引用的类被自动保留。这是必需的,因为 Android 框架通过反射访问这些应用程序入口点。

来自here

构建过程运行工具aapt自动创建配置文件bin/proguard.txt,基于AndroidManifest.xml和其他xml文件。然后构建过程将配置文件传递给 ProGuard。所以ProGuard本身确实不考虑AndroidManifest.xml,但是aapt+ProGuard会考虑。

【讨论】:

    【解决方案2】:

    来自ProGuard FAQ

    ProGuard 是否处理 Class.forName 调用?

    是的。 ProGuard 会自动处理 Class.forName("SomeClass") 和 SomeClass.class 等结构。引用的类在收缩阶段被保留,字符串参数在混淆阶段被适当地替换。 使用可变字符串参数,通常无法确定它们的可能值。例如,它们可能是从配置文件中读取的。但是,ProGuard 会注意到一些结构,例如“(SomeClass)Class.forName(variable).newInstance()”。这些可能表明类或接口 SomeClass 和/或其实现可能需要保留。开发人员可以相应地调整他的配置。

    所以,ProGuard 比你想象的更聪明:它会自动检测和处理使用 forName() 的简单案例。即使在 Android 清单文件中没有引用该类,ProGuard 也会在您对 forName() 的调用中混淆类 中的类名。

    对于活动,如果您同时被这种行为和作为构建过程一部分的 Android 特定输入 ProGuard 双重覆盖,我不会感到惊讶,正如@laalto 在他的回答中提到的那样。

    【讨论】:

      猜你喜欢
      • 2016-08-18
      • 1970-01-01
      • 2013-03-25
      • 2012-06-13
      • 1970-01-01
      • 2012-07-22
      • 2014-05-02
      • 2021-08-18
      • 1970-01-01
      相关资源
      最近更新 更多