在现实世界中,如果您要为android项目编写ui测试,请在从Android Studio中按“运行”后,它将组装两个应用程序:“your.cool.app”和“your.cool.app.test”。测试应用将在android中显示类似以下内容:

<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
                 android:targetPackage="your.cool.app"/>

这实际上意味着,如果同时安装它们和您的测试应用程序,则它们将与真正的应用程序合并-所有依赖项(第三方库等)都将在一个运行时类路径中。因此,如果两个应用程序将具有某种类型的库,则无法将它们合并,因为不可能在运行时类路径中过多地包含多个类,否则您将获得重复的类异常。

这就是为什么您具有Android插件功能的原因,该功能允许您为测试应用程序androidTestImplementation添加依赖项。因此,如果添加两个类似的依赖项,例如:
implementation 'com.google.android.material:material:1.0.0'
androidTestImplementation 'com.google.android.material:material:1.0.0'

Gradle将解决此类问题。因此,对于真正的应用程序,它将添加到编译和运行时类路径中;对于测试应用程序,它将仅添加到编译类路径中(这就是为什么您可以从测试类中的依赖项中导入所有内容的原因)

由于某种原因,我正在使用两个不同的应用程序。当我为这两个应用程序添加依赖项时:
implementation 'com.google.android.material:material:1.0.0'

我将有一个Duplicate classes '...'
是的,最好的解决方案是制作一个单声道存储库,然后让Android Gradle Plugin解决此问题...
但是我不能,因为在这种情况下,没有主代码就无法共享测试代码。

是的,我们已经有一个'compileOnly',它可以完美工作(它只添加了一个依赖项来编译类路径),但是它仅适用于 JAR和。所以我需要一个像'compileOnly'这样的 Artifact 配置,但是对于 AAR

我已经尝试过的:
allprojects {
    createCompileOnlyAarConfiguration(project)
}

def createCompileOnlyAarConfiguration(Project project) {

    def compileOnlyAarConf = project.configurations.create('compileOnlyAar')
    compileOnlyAarConf.visible = false
    compileOnlyAarConf.transitive = false

    project.gradle.addListener(new DependencyResolutionListener() {
        @Override
        void beforeResolve(ResolvableDependencies resolvableDependencies) {
            compileOnlyAarConf.dependencies.each { dependency ->
                project.dependencies.add('compileOnly', dependency)
            }
            project.gradle.removeListener(this)
        }

        @Override
        void afterResolve(ResolvableDependencies resolvableDependencies) {
        }
    })
}

所以现在我可以做类似的事情:
dependencies {
    compileOnlyAar 'com.google.android.material:material:1.0.0'
}

通过这种配置,我可以使用这些依赖关系中的所有类,但是在最终的dex文件中,其中没有使用过的方法的引用。这就是为什么我得到java.lang.NoSuchMethodError: java.lang.NoSuchMethodError: No static method
我还发现了gradle plugin,实际上添加了一个'compileOnlyAar'配置,但它仅适用于Java模块

我在gradle环境中不是很好,所以如果有人可以指出我如何为AAR Artifact 制作“compileOnly”,那将很酷。

更新:
“出于某种原因,我正在使用两个不同的应用程序”-意味着我也有“your.cool.app”和“your.cool.app.test”应用程序。但是它们具有自己的gradle依赖关系,并且测试应用在AndroidManifest中具有instrumentation属性。 'your.cool.app'-主代码库,'your.cool.app.test'-所有ui测试。安装完两者后,我只是通过adb shell am instrument运行测试。测试应用程序和主应用程序需要依赖项com.google.android.material:material:1.0.0,因此它们都包含:
dependencies {
   implementation 'com.google.android.material:material:1.0.0'
}

因此,正如我所说,如果同时安装两个应用程序并通过adb shell am instrument启动测试,我将得到重复的类异常,因为两个二进制文件在运行时类路径中都将是两次。

为什么我需要这种结构?没有主代码库,我只能共享测试应用程序。所以我没有办法制作标准的monorepo

最佳答案

在android studio的右侧,转到gradle>您的libraryapp>运行配置>组装.AAR将出现在您所选项目的输出文件夹中

07-28 03:18
查看更多