使用 android studio 混淆多个模块

Obfuscating multiple modules with android studio

我在使用 gradle proguard 时遇到问题...我有以下模块:

build.gradle 个文件: - 应用程序:

buildTypes {
       release {
           minifyEnabled true
           proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
       }
 }
dependencies {
   compile fileTree(dir: 'libs', include: ['*.jar'])
   compile project(':ModuleA')
   compile project(':ModuleC')
   wearApp project(':Wear')
}

模块A:

buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}
dependencies {
  compile fileTree(dir: 'libs', include: ['*.jar'])
  compile project(':ModuleB')
}

模块B:

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

模块C:与模块B相同。

穿:

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

**我只写了重要的几行

我的问题是,如果我使用该配置生成签名 APK,当我将它安装到设备上时,它会崩溃并出现以下异常:

java.lang.NoSuchFieldError: no field with name='peer' signature='J' in class Lcom/package/ClassInJar;

它在模块 A 的 libs 文件夹中的 jar 中包含的 class 中崩溃。

如果我在所有模块中将 minifyEnabled 设置为 false,它不会崩溃,但我更喜欢混淆代码。如果我在库模块中将 minifyEnabled 设置为 true,它不会编译,它会向我显示此异常:

Error:Execution failed for task ':ModuleB:proguardRelease'.

java.io.IOException: The output jar is empty. Did you specify the proper '-keep' options?

首先重要的是要了解 proguard 起着两个主要作用:

  • 当 proguard obfuscate 它实际上需要你所有的 classes,classes 成员,方法等并更改它们的名称所以它会变得乱码.这样一来,别人就很难对您的代码进行逆向工程。
  • 收缩代码,这样每个未使用的class、class成员、方法等都在编译时被丢弃,使你的apk更苗条.

就 "minify" 而言,这是没有必要的,尽管它可能会为您节省几千字节的空间。你可以把它关掉,它会没事的。

至于崩溃 - 发生这种情况是因为您的部分代码试图到达 class ,它的名称可能被混淆了,因此丢失了。
尝试为混淆器设置规则。可以这样做:

  • 找到 'proguard-rules.pro' 文件,该文件位于 "app" 文件夹中 'build.gradle' 文件的旁边(下图)。

  • 接下来您需要为特定的 classes/class 成员/方法/等添加 'keep' 规则,这样就不会在这些元素上发生混淆。您在文件中注释掉了示例,例如:

    -保持class成员class fqcn.of.javascript.interface.for.webview { public *; }


这意味着“不要混淆给定 class.

中 public 的任何 class 成员

但是,保留有很多变体。
有关 'keep' 变体的更多信息,请查看此文档以及 link 中的示例(当您单击一个项目时):Keep options

祝你好运=)