IntelliJ, Android и Gradle

Я пытаюсь заставить мой существующий Android-проект работать с gradle и IntelliJ 12. Раньше он работал с maven, но это не казалось таким гибким, как gradle, и из того, что я думаю, я узнал, это то, что мне нужно меньше подпапки.

Мой проект Android разделен на чистую библиотеку Java (: core) и фактическое приложение (: android). Эти два проекта находятся в моей основной папке проекта.

~-+MainProject
  |--+core
  |  L--build.gradle
  |--+android
  |  L--build.gradle
  |--build.gradle
  L--settings.gradle 

Я думаю, что идеальное решение для работы с Gradle — рассматривать проект (: core) и (: android) как вложенные проекты, что означает, что я могу просто использовать свой cmd в исходной папке MainProject для запуска задач Gradle.

Однако я столкнулся с разными проблемами:

  1. Gradle dependencies are only included in the core project
    • that means neither in the instrumentatetionTest nor in the main project files are any directories correctly set as source / test directories
    • IntelliJ doesn't resolve any classes that I added as dependencies in gradle (AndroidSDK, junit, mockito, those from the :core project)
      • tried to use the plugin 'idea' but either I used it wrong or it didn't solve the problem
  2. I get duplicate dependency Error for building the APK
    • must have something to do with junit:4.11 and mockito-core:1.9.5 that I added
    • what I tried:
      • deleting the dependencys -> build fails cause some classes of course could'nt be resolved
      • переход на junit: 4.5+, как было предложено в какой-то другой теме -> вообще никаких изменений

Вот конфигурации *.gradle

Основной проект: -- settings.gradle

include ':core', ':android'

-- build.gradle

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.6.+'
    }
}

subprojects {
    repositories {
        mavenLocal()
        maven { url "http://repo.maven.apache.org/maven2" }
    }
}

:ядро -- build.gradle

apply plugin: 'java'

dependencies {
    testCompile 'junit:junit:4.11'
    testCompile 'org.mockito:mockito-core:1.9.5'
}

: андроид

apply plugin: 'android'

repositories {
    mavenCentral()
}

dependencies {
     compile project(":core")

     compile 'com.google.android:android:4.1.1.4'

     instrumentTestCompile 'junit:junit:4.11'
     instrumentTestCompile 'org.mockito:mockito-core:1.9.5'
     instrumentTestCompile 'com.google.dexmaker:dexmaker:1.0'
     instrumentTestCompile 'com.google.dexmaker:dexmaker-mockito:1.0'

     instrumentTestCompile 'com.jayway.android.robotium:robotium-solo:3.6'
} 

/* ... androidSettings

Я надеюсь, что кто-то может помочь мне с этим

MFG Дорнаталь


person Dornathal    schedule 21.11.2013    source источник


Ответы (1)


Итак, у вас есть правильная идея, но есть несколько изменений, которые вам все еще нужны.

Ваш корневой файл build.gradle должен выглядеть следующим образом:

subprojects {
    repositories {
        mavenCentral()
    }
}
  • Вам нужно только включить mavenLocal(), если вы используете локально установленный репозиторий. Большинство людей этого не делают, и ничто в вашем проекте не указывает на то, что вам это нужно.
  • mavenCentral() можно использовать для замены URL-адреса maven, который вы использовали.
  • Нам нужно только изменить скрипт сборки для проекта Android, поэтому мы должны локализовать его в build.gradle проекта Android.

Ваши settings.gradle и build.gradle для основного проекта хороши.

Однако ваш build.gradle для проекта Android нуждается в некоторых изменениях:

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.6.+'
    }
}

apply plugin: 'android'

dependencies {
    compile project(":core")

    instrumentTestCompile 'com.jayway.android.robotium:robotium-solo:3.6'
}
  • Включая плагин для Android, мы напрямую связываемся с установленным SDK. Это означает, что нам больше не нужно включать зависимость Android: compile 'com.google.android:android:4.1.1.4'.
  • Нам не нужно включать junit. Он предоставляется SDK, поэтому мы будем использовать его. Следует отметить, что SDK включает только JUnit 3.
  • Нам не нужно включать mockito и dexmaker, если только мы не используем их для тестов Android. Если он используется только для тестов библиотеки Java, он нам здесь не нужен.

Чтобы ответить на ваши вопросы:

  1. Я не уверен, что вы спрашиваете здесь. Это может помочь, если вы будете структурировать свой проект, включая каталоги, в которых у вас есть файлы и тому подобное.
  2. Ваша догадка верна. Компания Hamcrest, которая предоставляет средства сопоставления для тестов, внесла критическое изменение в свой API между версиями 1.1 и 1.3. JUnit 4.11 зависит от Hamcrest 1.3. Однако Mockito 1.9.5 зависит от Hamcrest 1.1. Поэтому, когда оба включены, 1.3 переопределяет 1.1, и Mockito больше не работает. Возврат к JUnit 4.5 также является проблемой. Junit 4.5 включает jar Hamcrest 1.1 как файл, а не как зависимость в POM. Так что это вызовет проблемы, когда у нас есть 2 версии одного и того же файла. JUnit 4.10 — это то, что вам нужно. Это зависит от Hamcrest 1.1 и включает его в POM, а не в виде файла. Выиграй, выиграй! У меня тоже были проблемы с этим, и лучший способ понять это — просто посмотреть файлы POM на Maven Central и посмотреть, что они мне говорят.

Последнее замечание. Intellij 12 не может обрабатывать многопроектные сборки Gradle. Для этого вам нужно переключиться на Android Studio или Intellij 13.

person MariusVolkhart    schedule 04.01.2014
comment
Супер хороший ответ, Мариус. Я думаю, что его вопрос в пункте 1 касается того, как указать исходные каталоги тестов из файла android build.gradle. Но и мне не совсем понятно. Я использую AndroidStudio, поэтому не уверен, что мой ответ будет здесь полезен. Спасибо за совет JUnit;) - person khose; 05.02.2014
comment
Поскольку Android Studio — это IntelliJ с уже включенным ADT, я думаю, что не должно быть никакой разницы. - person Dornathal; 29.03.2014
comment
Конечно, для jUnit 4.11 ему нужна была зависимость, если SDK содержал только JUnit 3. - person RichieHH; 31.03.2014