为什么Proguard在Android中保留Activity类?

时间:2013-12-16 20:09:28

标签: android proguard

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

我正在使用

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

作为配置文件,不做任何改动。

在此文件中,我可以看到有关活动的唯一声明:

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);
}

由此可见,ProGuard会忽略活动类名,而某些方法会保留原样。这是可以理解的。

但是,在我的应用程序中,我使用

从字符串创建一个Activity类
Class.forName("my.app.MyActivity")

然后我开始这个活动,它开始很好。

但这意味着Activity派生类不会被混淆?? 。它应该失败,因为ProGuard没有-keep class的{​​{1}}指令,它只有Activity

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

2 个答案:

答案 0 :(得分:11)

因为活动列在清单和引用的类中,所以会自动保留。这是必需的,因为Android框架通过反射访问这些应用程序入口点。

来自here

  

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

答案 1 :(得分:3)

来自ProGuard FAQ

  

ProGuard是否处理Class.forName调用?

     

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

因此,ProGuard比您预期的更聪明:它会自动检测并处理forName()使用的简单案例。即使Android清单文件中未引用该类,ProGuard也会在您对forName()的调用中对类中的类名进行模糊处理。

对于活动,如果你被这种行为以及ProGuard的Android特定输入所覆盖,那就不会让我感到惊讶,正如@laalto在他的回答中提到的那样。