所以,我想向我的项目添加一个外部库。库本身很小,大约有 300 个方法。但它的 proguard 配置被配置得非常自由。我在一个准系统项目上运行了一个简单的测试,有/没有库,有/没有 proguard,这就是我想出的
Proguard Lib Method Count
N N 15631
Y N 6370
N Y 15945
Y Y 15573
如您所见,启用 proguard 后,计数约为 6000。但是当我添加库时,尽管库本身只有约 300 个方法,但计数猛增至约 15000 个。
所以我的问题是,如何忽略这个特定库的混淆器配置?
更新:
现在用android gradle插件是不可能的。我发现 android bug 根本没有优先级。请避免在回答中提到“这是不可能的”,并保持问题的开放性,直到找到解决方法或做出正式决定为止。否则,您将获得一半的赏金,而不会增加任何价值。谢谢!
在这种特定情况下,您有几种选择:
将以下内容添加到您的 build.gradle 中:
afterEvaluate {
// All proguard tasks shall depend on our filter task
def proguardTasks = tasks.findAll { task ->
task.name.startsWith('transformClassesAndResourcesWithProguardFor') }
proguardTasks.each { task -> task.dependsOn filterConsumerRules }
}
// Let's define our custom task that filters some unwanted
// consumer proguard rules
task(filterConsumerRules) << {
// Collect all consumer rules first
FileTree allConsumerRules = fileTree(dir: 'build/intermediates/exploded-aar',
include: '**/proguard.txt')
// Now filter the ones we want to exclude:
// Change it to fit your needs, replace library with
// the name of the aar you want to filter.
FileTree excludeRules = allConsumerRules.matching {
include '**/library/**'
}
// Print some info and delete the file, so ProGuard
// does not pick it up. We could also just rename it.
excludeRules.each { File file ->
println 'Deleting ProGuard consumer rule ' + file
file.delete()
}
}
使用 DexGuard (7.2.02+) 时,您可以将以下代码片段添加到 build.gradle 中:
dexguard {
// Replace library with the name of the aar you want to filter
// The ** at the end will include every other rule.
consumerRuleFilter '!**/library/**,**'
}
请注意,逻辑与上面的 ProGuard 示例相反,consumerRuleFilter 将仅包含与模式匹配的消费者规则。
如果您使用 R8(自 Android Gradle 插件 3.4.0 起取代了 ProGuard) - 您可以通过将以下解决方法添加到模块的
build.gradle
: 来过滤掉特定的消费者规则文件
tasks.whenTaskAdded { Task task ->
// Once 'minifyEnabled' is set to 'true' for a certain build type/variant -
// a 'minify<variantName>WithR8' task will be created for each such variant
//
// - This task is implemented by com.android.build.gradle.internal.tasks.R8Task
// - R8Task extends from ProguardConfigurableTask
// - ProguardConfigurableTask exposes property 'configurationFiles'
// - configurationFiles contains all files that will be contributing R8 rules
// - configurationFiles is mutable (its type is ConfigurableFileCollection)
//
// Thus - we can overwrite the list of files and filter them out as we please
//
// More details: https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:build-system/gradle-core/src/main/java/com/android/build/gradle/internal/tasks/R8Task.kt
if (task.name.startsWith("minify") && task.name.endsWith("WithR8")) {
afterEvaluate {
def filteredList = task.configurationFiles.filter {
// Example paths in this collection:
// /Users/me/MyProject/myModule/proguard-rules.pro
// (for library dependencies) /Users/me/.gradle/caches/<...>/okhttp3.pro
// The below filter condition will, for example, exclude consumer ProGuard rules file from the AndroidX RecyclerView library
!it.path.contains("recyclerview-1.1.0")
}
task.configurationFiles.setFrom(filteredList.files)
}
}
}
上述解决方法已确认适用于 Android Gradle 插件 4.2.2
如果决定依赖这样的解决方法 - 添加某种自动检查和/或测试以确保此过滤有效可能是个好主意。鉴于该解决方案非常脆弱,并且可能会随着 Android Gradle 插件的未来更新而崩溃。
编辑:在 Gradle 7.3 中,有一种方法可以指定忽略保留规则的依赖项:https://developer.android.com/reference/tools/gradle-api/7.3/com/android/build/api /dsl/KeepRules#ignoreExternalDependency(kotlin.Array)
例如:
buildTypes {
release {
optimization.keepRules {
it.ignoreExternalDependencies("androidx.lifecycle:lifecycle-runtime")
}
}
}
旧答案:受到 Jonas 答案的启发,针对 Kotlin DSL 进行了修改,并确认在 Android Gradle 插件 7.2.1 上工作:
import com.android.build.gradle.internal.tasks.ProguardConfigurableTask
afterEvaluate {
// Get each ProguardConfigurableTask
tasks.withType(ProguardConfigurableTask::class.java).forEach { task ->
// Remove proguard rules from lifecycle-runtime library
val filteredConfigurationFiles = task.configurationFiles.filter { file ->
!file.path.contains("lifecycle-runtime")
}
task.configurationFiles.setFrom(filteredConfigurationFiles)
}
}