Как сделать эквивалент 'compileOnly' для артефактов AAR? - PullRequest
3 голосов
/ 02 апреля 2020

В реальном мире, если вы пишете пользовательские тесты для проекта android, после нажатия «Выполнить» из Android Studio он соберет два приложения: «your.cool.app» и «your.cool». app.test. Тестовое приложение будет иметь в android манифест что-то вроде:

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

Что на самом деле будет означать, что если вы установите их оба, ваше тестовое приложение будет объединено с реальным - все зависимости party libs et c ..) будет находиться в одном пути к классам во время выполнения. Таким образом, если два приложения будут иметь какие-то библиотеки, их нельзя объединить, поскольку невозможно иметь более одного класса в пути к классам во время выполнения, иначе вы получите исключение дублированных классов .

* 1007. * Вот почему у вас есть функциональность Android Плагин, который позволяет вам добавлять зависимости для тестового приложения - androidTestImplementation. Поэтому, если вы добавите две аналогичные зависимости, такие как:
implementation 'com.google.android.material:material:1.0.0'
androidTestImplementation 'com.google.android.material:material:1.0.0'

Gradle решит эту проблему. Таким образом, для реального приложения оно добавит compile и runtime classpath, а для тестового приложения оно добавит только для compile classpath (поэтому вы можете импортировать все вещи из зависимость в тестовых классах)

По какой-то причине я работаю с двумя разными приложениями. И когда я добавлю зависимость для этих двух приложений, таких как:

implementation 'com.google.android.material:material:1.0.0'

, у меня будет Duplicate classes '...'

Да, лучшее решение - сделать моно-репо и позволить Android Плагин Gradle разрешает эту проблему ... Но я не могу, поскольку в этой ситуации вы не можете поделиться своим тестовым кодом без основного кода.

Да, у нас уже есть 'compileOnly', который отлично работает (он только добавляет зависимость для компиляции classpath), но он работает только для JARs . Поэтому мне нужна конфигурация артефакта, такая как 'compileOnly', но для 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 , который фактически добавляет конфигурацию 'compileOnlyAar', но работает только с java module

Я не очень хорош в окружающей среде, поэтому было бы здорово, если бы кто-нибудь указал мне, как сделать 'compileOnly' для артефактов AAR.

ОБНОВЛЕНИЕ:"По какой-то причине я ' «Я работаю с двумя разными приложениями» - означает, что у меня также есть приложения «your.cool.app» и «your.cool.app.test». Но у них есть собственные зависимости gradle, и тестовое приложение имеет атрибут instrumentation в AndroidManifest. 'your.cool.app' - основная кодовая база, 'your.cool.app.test' - все тесты пользовательского интерфейса. После установки обоих я просто запускаю тесты через 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, я получу дубликат исключение класса , так как оба двоичных файла будут дважды в пути к классам во время выполнения.

Зачем мне нужна эта структура? Я могу поделиться только тестовым приложением без основной кодовой базы. Так что у меня нет возможности сделать стандартный монорепо

1 Ответ

0 голосов
/ 15 апреля 2020

Справа от android stud ios goto gradle> ваше библиотечное приложение> Выполнить конфигурации> asssemble .AAR будет присутствовать в выходной папке выбранного вами проекта

...