簡體   English   中英

如何從AAR依賴中排除特定資源?

[英]How To Exclude Specific Resources from an AAR Depedency?

模塊的build.gradle文件是否有一種相當簡單的方法來指示應該排除依賴項中的某些文件? 我特別想從AAR中排除某些資源。


LeakCanary是一個有趣的庫,可幫助追蹤內存泄漏。 但是,它具有21或更高版本的compileSdkVersion的無證要求。 雖然大多數項目都不應該有這個問題,但是圖書館沒有充分理由要求某個compileSdkVersion 開發團隊可能已凍結其compileSdkVersion作為一般策略的一部分,僅將這些設置更改為其應用程序或其他內容的主要版本更新的一部分。

在這種情況下,至少對於compileSdkVersion ,需要compileSdkVersion的唯一原因是AFAICT,因為AAR有一個res/values-v21/目錄,其中包含一個繼承自Theme.Material的主題定義。 診斷活動使用此主題。 最終用戶從未見過該活動,只有debug版本中的開發人員才能看到該活動。 坦率地說,主題方面的活動看起來並不重要。 強制使用21的compileSdkVersion只是為了讓診斷活動具有某個主題,恕我直言,愚蠢。

如果作為compile指令的一部分,我們可以說“嘿,請跳過res/values-v21/來自這個AAR,m'kay?”。 由於-v21主題只是提供了其他地方定義的主題的替代定義,因此刪除-v21主題不會破壞構建或在運行時中斷事物,而只會給我們一個以Holo主題的診斷活動。

我沒有看到這個答案如何與依賴關系一起工作。 我也不確定它是否完整,它似乎似乎沒有得到支持 它也沒有真正符合“簡單”的條件 - 我不希望有人嘗試將它放在build.gradle文件中,只是為了阻止像LeakCanary這樣的診斷庫中的單個文件。

那么,是否有一些比這更簡單的東西適用於當前版本的Android插件Gradle?

編輯:

為您寫了高級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()方法調用。

嘗試使用compileOnly關鍵字來標記資源僅用於編譯。

dependencies {
      compileOnly fileTree(include: ['*.jar'], dir: 'libs')
}

我相信你可以使用Android Gradle Plugin DSL的PackagingOptions工具更優雅地解決這個問題。

我能夠自己使用它來排除我在項目中不需要AAR引入的一些本機庫。

android {
    ...
    packagingOptions {
        exclude '/lib/armeabi-v7a/<file_to_exclude>'
    }
}

對於問題中概述的案例,我相信這會奏效:

android {
    ...
    packagingOptions {
        exclude '/res/values-v21/<file_to_exclude>'
    }
}

是的,你可以使用Proguard

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM