Как исключить конкретные ресурсы из-за зависимостей AAR?
Есть ли достаточно простой способ для файла модуля build.gradle
указать, что определенные файлы из зависимости должны быть исключены? Меня особенно интересует исключение определенных ресурсов из AAR.
LeakCanary - интересная библиотека, помогающая отслеживать утечки памяти. Однако у него есть недокументированное требование compileSdkVersion
от 21 или выше. Хотя в большинстве проектов не должно быть проблем с этим, неприемлемо, чтобы библиотека требовала определенного compileSdkVersion
без уважительной причины. Команда разработчиков, возможно, заморозила их compileSdkVersion
как часть общей политики, чтобы изменять эти параметры только в качестве основных обновлений версии своего приложения или чего-то еще.
В этом случае, по крайней мере, для v1.3.1 LeakCanary требуется единственная причина compileSdkVersion
, AFAICT, потому что AAR имеет каталог res/values-v21/
, содержащий определение темы, которое наследуется от Theme.Material
. Эта тема используется диагностической деятельностью. Эта деятельность никогда не рассматривается конечными пользователями, только разработчиками в debug
builds. Честно говоря, то, что эта деятельность выглядит, по-тематически, на самом деле не имеет значения. Принуждение compileSdkVersion
из 21 только для того, чтобы эта диагностическая деятельность имела определенную тему, ИМХО, глупо.
Было бы неплохо, если бы в рамках директивы compile
мы могли бы сказать "эй, пожалуйста, пропустите res/values-v21/
из этого AAR, m'kay?". Поскольку тема -v21
просто предоставляет альтернативное определение темы, заданной в другом месте, отбрасывание темы -v21
не приведет к нарушению сборки или разрыва вещей во время выполнения, а просто даст нам Holo
-тематическую диагностическую деятельность.
Я не вижу, как этот ответ работает с зависимостями. Я также не уверен, если он завершен, и он, безусловно, не поддерживается. Это также действительно не квалифицируется как "простой" — Я бы не ожидал, что кто-то попытается удалить это в файле build.gradle
, чтобы заблокировать один файл из диагностической библиотеки, такой как LeakCanary.
Итак, есть ли что-то более простое, чем это работает с текущими выпусками Android-плагинов для Gradle?
Ответы
Ответ 1
EDIT:
Написал расширенную задачу gradle для вас:
final List<String> exclusions = [];
Dependency.metaClass.exclude = { String[] currentExclusions ->
currentExclusions.each {
exclusions.add("${getGroup()}/${getName()}/${getVersion()}/${it}")
}
return thisObject
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile ('com.android.support:appcompat-v7:20.+')
debugCompile ('com.squareup.leakcanary:leakcanary-android:1.3.1')
.exclude("res/values-v21/values-v21.xml")
releaseCompile ('com.squareup.leakcanary:leakcanary-android-no-op:1.3.1')
}
tasks.create("excludeTask") << {
exclusions.each {
File file = file("${buildDir}/intermediates/exploded-aar/${it}")
println("Excluding file " + file)
if (file.exists()) {
file.delete();
}
}
}
tasks.whenTaskAdded({
if (it.name.matches(/^process.*Resources$/)) {
it.dependsOn excludeTask
}
})
Теперь вы можете использовать метод .exclude()
для каждой зависимости, предоставляя в список путей, которые вы хотите исключить из указанной зависимости.
Кроме того, вы можете складывать вызовы методов .exclude()
.
Ответ 2
Я считаю, что вы можете более эффективно решить эту проблему, используя PackagingOptions средство для Android Gradle Плагин DSL.
Я смог использовать это сам, чтобы исключить некоторые родные библиотеки, которые мне не нужны, в AAR, в моем проекте.
android {
...
packagingOptions {
exclude '/lib/armeabi-v7a/<file_to_exclude>'
}
}
В случае, описанном в вопросе, я считаю, что это сработает:
android {
...
packagingOptions {
exclude '/res/values-v21/<file_to_exclude>'
}
}
Ответ 3
Да, вы можете использовать Proguard
buildTypes {
release {
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
debug {
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
}