使用Android Gradle插件3.0.1时,无法解决assembleAndroidTest任务的依赖项。

3
我正在更新我们的项目,使用Gradle 4.1和Android Gradle插件3.0.1。我已经将我们的依赖配置更新为新配置,并且项目可以成功编译。但是,在编译android测试(assembleAndroidTest Gradle任务)时,有许多未解决的依赖项(包括Kotlin标准库的顶级函数)。我怀疑Proguard可能会导致这个问题(尽管在更新Gradle之前没有),但即使添加显式规则来保留符号/类也没有帮助。我们使用Kotlin 1.2.10和Kotlin-Kapt插件。
感谢任何帮助。
1个回答

0
我在调试时不使用ProGuard,但是以下的答案似乎有用。我建议您按照迁移指南重新修订Gradle配置,并首先清除和无效化缓存。
Proguard
请参考这个问题和这个答案,了解如何在Proguard中使用Kotlin。
在您的build.gradle文件中禁用这些指令以丢弃Proguard。
minifyEnabled false
shrinkResources false

为 Kotlin 配置 Proguard。

You don't need to do anything special. Kotlin works with ProGuard out of the box. But you may face some strange errors when processing your application with ProGuard. In this case just add:

-dontwarn kotlin.**

你也可以添加:

-keep class kotlin.** { *; }
-keep class kotlin.Metadata { *; }
-dontwarn kotlin.**
-keepclassmembers class **$WhenMappings {
    <fields>;
}
-keepclassmembers class kotlin.Metadata {
    public <methods>;
}
-assumenosideeffects class kotlin.jvm.internal.Intrinsics {
    static void checkParameterIsNotNull(java.lang.Object, java.lang.String);
}

检查以下相关问题,以确定是否为测试启用Proguard:

proguard gradle debug build but not the tests

指定在仪器化测试中使用的Proguard文件。

runProguard is old. It was replaced with minifyEnabled

With minifyEnabled (and other changes in new versions of Gradle) you will may encounter issues where the Proguard config works for your debug apk but not for the instrumentation tests. The apk created for instrumentation tests will use its own proguard file, so changing your existing proguard file will have no effect.

In this case, you need to specify the proguard file to use on the instrumentation tests. It can be quite permissive because it's not affecting your debug and release builds at all.

    // inside android block
    debug {
        shrinkResources true  // removes unused graphics etc
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        testProguardFile('test-proguard-rules.pro')
    }

启用混淆后的 Android 单元测试

添加自定义 Proguard 规则文件

/project/app/proguard-test-rules.pro

# Proguard rules that are applied to your test apk/code.
-ignorewarnings

-keepattributes *Annotation*

-dontnote junit.framework.**
-dontnote junit.runner.**

-dontwarn android.test.**
-dontwarn android.support.test.**
-dontwarn org.junit.**
-dontwarn org.hamcrest.**
-dontwarn com.squareup.javawriter.JavaWriter
# Uncomment this if you use Mockito
#-dontwarn org.mockito.**
The add the following to your build.gradle for your app. To use the proguard file when testing.

/project/app/build.gradle

android {
    debug {
        minifyEnabled true
        testProguardFile 'proguard-test-rules.pro'
    }
}

为测试添加一个构建类型

我通过添加一个额外的“dev”构建类型来解决了我的构建问题,在该构建类型中,我启用了proguard,但将其配置为保留我的自己包中的所有代码和一些特定的库类,这些库类仅从测试中使用。我还在dev构建类型中禁用了混淆,以便可以从IDE进行调试。

对于调试和发布版本,我使用我的“真实”proguard设置,包括混淆和优化。

使用单独的测试模块

Separate test modules are now variant-aware. This means that specifying targetVariant is no longer necessary.

Each variant in the test module will attempt to test a matching variant in the target project. By default, test modules contain only a debug variant, but you can create new build types and new flavors to create new variants to match the tested app project. A connectedCheck task is created for each variant.

To make the test module test a different build type only, and not the debug one, use VariantFilter to disable the debug variant in the test project, as shown below:

android {
    variantFilter { variant ->
        if (variant.buildType.name.equals('debug')) {
            variant.setIgnore(true);
        }
    }
}

If you want a test module to target only certain flavors or build types of an app, you can use the matchingFallbacks property to target only the variants you want to test. This also prevents the test module from having to configure those variants for itself.


Gradle

请修改您的Gradle配置。为了构建使用Kotlin编写的Android项目

  • 设置kotlin-android Gradle插件并将其应用到您的项目中。
  • 添加kotlin-stdlib依赖。

在IntelliJ IDEA / AS中,这些操作也可以通过调用以下操作来自动执行:

工具 | Kotlin | 配置项目中的Kotlin


kotlin-android

buildscript {
    ext.kotlin_version = '1.2.10'

    ...

    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'

kotlin-stdlib

不要忘记配置 标准库依赖项

repositories {
    mavenCentral()
}

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib"
}

使用迁移指南修改您的依赖配置。

注意:compileprovidedapk目前仍然可用

但是,在下一个主要版本的Android插件中,它们将被删除


手动提供版本

Starting with Kotlin 1.1.2, the dependencies with group org.jetbrains.kotlin are by default resolved with the version taken from the applied plugin.

You can provide the version manually using the full dependency notation like this:

compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"

解决方案

您还可以强制执行解决方案

configurations.all {
    resolutionStrategy {
        force "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    }
}

由于您正在使用 Android Gradle插件3.0.1

// Instead, because the new build model delays dependency resolution, you
// should query and modify the resolution strategy using the Variant API:
android {
    applicationVariants.all { variant ->
        variant.getCompileConfiguration().resolutionStrategy {
            ...
        }
        variant.runtimeConfiguration.resolutionStrategy {
            ...
        }
        variant.getAnnotationProcessorConfiguration().resolutionStrategy {
            ...
        }
    }
}

使用 Variant API 从测试配置中排除应用程序依赖项:

On previous versions of the Android plugin, you could exclude certain transitive dependencies of your app from your tests using the exclude keyword. However, with the new dependency configurations, you must do it at execution time using the Variant API:

android.testVariants.all { variant ->
    variant.getCompileConfiguration().exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp'
    variant.getRuntimeConfiguration().exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp'
}

Kotlin标准库扩展版本

If you're targeting JDK 7 or JDK 8, you can use extended versions of the Kotlin standard library which contain additional extension functions for APIs added in new JDK versions. Instead of kotlin-stdlib, use one of the following dependencies:

compile "org.jetbrains.kotlin:kotlin-stdlib-jdk7"
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8"

In Kotlin 1.1.x, use kotlin-stdlib-jre7 and kotlin-stdlib-jre8 instead.


Kotlin 反射

If your project uses Kotlin reflection or testing facilities, you need to add the corresponding dependencies as well:

compile "org.jetbrains.kotlin:kotlin-reflect"
testCompile "org.jetbrains.kotlin:kotlin-test"
testCompile "org.jetbrains.kotlin:kotlin-test-junit"

Kapt

查看Kotlin注解处理工具(kapt)的描述。

应用kotlin-kapt Gradle插件:

apply plugin: 'kotlin-kapt'

Proguard 不用于测试。 - Dawid Hyży
应该这样做。否则,你怎么知道你的代码不会因为ProGuard问题在运行时崩溃? - Martin Marconcini
Proguard 在生成你的 APK 的发布版本时被调用,而不是测试构建。 - AouledIssa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接