Подтвердить что ты не робот

Как исключить конкретные ресурсы из-за зависимостей 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?

4b9b3361

Ответ 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'
    }
}