首页 文章

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

提问于
浏览
8

我已将 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);
}

由此可见,ProGuard忽略了 Activities 类名,而某些方法保留原样 . 这是可以理解的 .

但是,在我的应用程序中,我然后使用字符串创建一个活动类

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

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

But that means Activity-derived classes are not obfuscated?? . 它应该失败,因为ProGuard没有 -keep class-keep class 指令,它只有 -keepclassmembers.

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

2 回答

  • 10

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

    here

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

  • 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在他的回答中提到了构建过程的一部分 .

相关问题