java - Android gradle : Exclude file from external dependencies

标签 java android kotlin

我添加了com.eftimoff:android-pathview:1.0.8@aar到我的项目,但当我运行应用程序时,我收到此错误:

Cause: duplicate entry: META-INF/MANIFEST.MF

这是pathview外部库中的文件:

enter image description here

现在我想排除META-INF文件夹,所以我将其添加到模块 gradle 中:

android {
...
    packagingOptions {
        exclude 'META-INF/*'
    }
}

但我仍然遇到上述错误。

我写了像 this suggestion 这样的 gradle 脚本

当我像这样添加库时: implementation ('com.eftimoff:android-pathview:1.0.8@aar').exclude("META-INF/MANIFEST.MF")

我收到此错误:

FAILURE: Build failed with an exception.

* Where:
Build file 'D:\Projects\Android\Mvvm\Kotlin\MovieDb\app\build.gradle' line: 80

* What went wrong:
A problem occurred evaluating project ':app'.
> Could not find method leftShift() for arguments [build_37vlhf9la1wtl8koroxp1kll7$_run_closure4@b32cc6a] on task ':app:excludeTask' of type org.gradle.api.DefaultTask.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

CONFIGURE FAILED in 0s
Could not find method leftShift() for arguments [build_37vlhf9la1wtl8koroxp1kll7$_run_closure4@b32cc6a] on task ':app:excludeTask' of type org.gradle.api.DefaultTask.
Open File

这就是 tasks.create("excludeTask") << {我有错误。 所以我改变了task.create()对此:

tasks.create("excludeTask")  {
    doLast{
        exclusions.each {
            File file = file("${buildDir}/intermediates/exploded-aar/${it}")
            println("Excluding file " + file)
            if (file.exists()) {
                file.delete()
            }
        }
    }
}

这些错误消失了,但我仍然再次遇到此错误:

Cause: duplicate entry: META-INF/MANIFEST.MF

此脚本似乎适用于 resources现在我想排除文件夹内的文件。

这是完整的 gradle:

apply plugin: 'com.android.application'

apply plugin: 'kotlin-android'

apply plugin: 'kotlin-android-extensions'

android {

    // Enables data binding.
    dataBinding {
        enabled = true
    }

    compileSdkVersion 29
    buildToolsVersion "29.0.2"
    defaultConfig {
        applicationId "com.t.moviedb"
        minSdkVersion 19
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

//    packagingOptions {
//        exclude '/META-INF/*'
//    }
//    aaptOptions {
//        ignoreAssetsPattern "!META-INF/MANIFEST.MF"
//        ignoreAssetsPattern "META-INF/MANIFEST.MF"
//    }
}


final List<String> exclusions = [];

Dependency.metaClass.exclude = { String[] currentExclusions ->
    currentExclusions.each {
        exclusions.add("${getGroup()}/${getName()}/${getVersion()}/${it}")
    }
    return thisObject
}


dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"

    // Support libraries
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.fragment:fragment:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'

    // Android KTX
    implementation 'androidx.core:core-ktx:1.1.0'

    // Testing
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

    //other
    implementation ('com.eftimoff:android-pathview:1.0.8@aar').exclude("META-INF/*")
}

tasks.create("excludeTask")  {
    doLast{
        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
    }
}) 

这是我的 gradle 版本:

\MovieDb>gradlew --version

------------------------------------------------------------
Gradle 5.4.1
------------------------------------------------------------

Build time:   2019-04-26 08:14:42 UTC
Revision:     261d171646b36a6a28d5a19a69676cd098a4c19d

Kotlin:       1.3.21
Groovy:       2.5.4
Ant:          Apache Ant(TM) version 1.9.13 compiled on July 10 2018
JVM:          1.8.0_231 (Oracle Corporation 25.231-b11)
OS:           Windows 10 10.0 amd64

和:

enter image description here

最佳答案

您的问题是由多个问题引起的,因此更难修复。 首先,Gradle Android 插件版本 3.5.2 似乎有一个错误,您无法从 apk 中删除这些额外的 list 文件。 作为解决方法,您可以将插件恢复到版本 3.5.1(不是 Android Studio,恢复插件版本就足够了)。

然后你看到了错误:

Cause: duplicate entry: META-INF/MANIFEST.MF

这是因为您暂时删除了该部分

packagingOptions {
    exclude 'META-INF/MANIFEST.MF'
}

来自您的 build.gradle,因为由于插件错误而无法工作。 最后,您看到了错误:

Duplicate class com.caverock.androidsvg.CSSParser found in modules androidsvg-1.2.1.jar (android-pathview-1.0.8.aar) and androidsvg-1.2.1.jar (com.eftimoff:android-pathview:1.0.8)

这是因为您在 libs/ 文件夹中包含了修改后的库,但忘记将其从 implementation {} 部分中删除,因此它被包含了两次.

关于java - Android gradle : Exclude file from external dependencies,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58796463/

相关文章:

java - 可以根据 Android 操作系统版本只加载特定的代码行吗?

android - 同一个 APK 中的多个应用

android - 如何在 Android 单元测试中访问资源?

kotlin - Ktor 客户端身份验证功能不发送授权 header

java - 手动超时java中的httpurlconnection

java - 如何测试基于 SSLEngine 的 TLS 实现?

java - 在 testng.xml 中引用测试组

android - IntentService 不会开始使用 AlarmManager

arrays - 使用映射的数组的自定义属性委托(delegate)

android - 混合类型的Kotlin ByteArray