Добавить зависимости через gradle для eclipse в проекте Android

у меня проблема с автоматическим добавлением зависимостей в проект eclipse android через gradle. У меня есть только небольшой опыт работы с gradle. До сих пор я построил два java-проекта с gradle. Одна банка и исполняемая банка. Это работает без проблем. Я использовал плагин eclipse для создания проекта eclipse и добавления зависимостей в путь сборки. Я добавил новые зависимости в скрипт gradle, запустил gradle с gradle eclipse, обновил свой проект, и зависимости существуют в пути сборки, и я могу их использовать. Вот важная часть этого сценария.

apply plugin: 'java'
apply plugin: 'eclipse'
repositories {
   mavenCentral()
}

dependencies {
   compile 'commons-io:commons-io:2.4'
}

Итак, теперь я попробовал его в сочетании с плагином для Android. Вот мой сценарий градиента отверстия.

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

apply plugin: 'android'
apply plugin: 'eclipse'

repositories {
mavenCentral()
}

dependencies {
compile 'org.apache.commons:commons-lang3:3.1'
}

android {
    compileSdkVersion 17
    buildToolsVersion "17"

    defaultConfig {
        minSdkVersion 14
        targetSdkVersion 17
    }
    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            resources.srcDirs = ['src']
            aidl.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
        }

        instrumentTest.setRoot('tests')
    }
}

Если я использую gradle eclipse, ничего не происходит. Затем я узнал, что плагин java добавляет зависимости в путь сборки. Поэтому я добавил

apply plugin: 'java'

к нему и получил ошибку, что плагин Java не совместим с плагином Android. Затем я нашел решение для автоматического копирования банок в папку lib проекта.

def libDir = file('libs')

task copyLibs(type: Copy) {

    doFirst {
        libDir.mkdirs()
    }
    from configurations.runtime
    into libDir
}

Но для этой задачи также нужен java-плагин для configurations.runtime. Мне нужен плагин Android для создания файла apk, поэтому удаление плагина Android не является решением. Есть ли у кого-нибудь идея, можно ли добавить зависимости к пути сборки или папке lib в проекте Ecipse, совместимом с плагином Android?

РЕДАКТИРОВАТЬ: Одна из моих идей заключалась в том, чтобы поместить java-плагин в eclipse-плагин, чтобы он применялся только тогда, когда будет применяться плагин eclipse. Что-то вроде этого:

apply plugin: 'eclipse'

eclipse{
    apply plugin: 'java'
}

Но я все еще получаю сообщение об ошибке, что плагины для Java и Android несовместимы. Возможно, я неправильно понимаю Gradle, но обычно плагин Java следует применять только тогда, когда я запускаю плагин eclipse, а не плагин Android. Я боюсь, что моего понимания и опыта работы с градиентом недостаточно, чтобы решить это таким образом или понять, почему это невозможно.


person Rafael    schedule 23.05.2013    source источник
comment
Привет, я не могу заставить ваше решение работать. Не могли бы вы проверить: stackoverflow. com/questions/28780426/?   -  person Jim    schedule 28.02.2015


Ответы (5)


Мое решение основано на Rafael, поскольку оно копирует зависимости в каталог libs, который используется только Android. Однако я иду дальше, чтобы полностью разобрать упомянутые AAR для использования в Eclipse.

Файл сборки Gradle

Добавьте следующее в конец вашего Android-проекта build.gradle :

task copyJarDependencies(type: Copy) {
    description = 'Used for Eclipse. Copies all dependencies to the libs directory. If there are any AAR files it will extract the classes.jar and rename it the same as the AAR file but with a .jar on the end.'
    libDir = new File(project.projectDir, '/libs')
    println libDir
    println 'Adding dependencies from compile configuration'
    configurations.compile.filter {it.name.endsWith 'jar'}.each { File file -> moveJarIntoLibs(file)}
    println 'Adding dependencies from releaseCompile configuration'
    configurations.releaseCompile.filter {it.name.endsWith 'jar'}.each { File file -> moveJarIntoLibs(file)}
    println 'Adding dependencies from debugCompile configuration'
    configurations.debugCompile.filter {it.name.endsWith 'jar'}.each { File file -> moveJarIntoLibs(file)}
    println 'Adding dependencies from instrumentTestCompile configuration'
    configurations.instrumentTestCompile.filter {it.name.endsWith 'jar'}.each { File file -> moveJarIntoLibs(file)}
    println 'Extracting dependencies from compile configuration'
    configurations.compile.filter {it.name.endsWith 'aar'}.each { File file -> moveAndRenameAar(file) }
    println 'Extracting dependencies from releaseCompile configuration'
    configurations.releaseCompile.filter {it.name.endsWith 'aar'}.each { File file -> moveAndRenameAar(file) }
    println 'Extracting dependencies from debugCompile configuration'
    configurations.debugCompile.filter {it.name.endsWith 'aar'}.each { File file -> moveAndRenameAar(file) }
    println 'Extracting AAR dependencies from instrumentTestCompile configuration'
    configurations.instrumentTestCompile.filter {it.name.endsWith 'aar'}.each { File file -> moveAndRenameAar(file) }
}

void moveJarIntoLibs(File file){
    println 'Added jar ' + file
        copy{
            from file
            into 'libs'
        }
}

void moveAndRenameAar(File file){
    println 'Added aar ' + file
    def baseFilename = file.name.lastIndexOf('.').with {it != -1 ? file.name[0..<it] : file.name}

    // directory excluding the classes.jar
    copy{
        from zipTree(file)
        exclude 'classes.jar'
        into 'libs/'+baseFilename
    }

    // Copies the classes.jar into the libs directory of the expoded AAR.
    // In Eclipse you can then import this exploded ar as an Android project
    // and then reference not only the classes but also the android resources :D 
    copy{
        from zipTree(file)
        include 'classes.jar'
        into 'libs/' + baseFilename +'/libs'
        rename { String fileName ->
            fileName.replace('classes.jar', baseFilename + '.jar')
        }
    }
}

Создание с помощью Gradle

Бегать :

"gradle clean build"

Вы должны найти все зависимости и развернутые файлы AAR в каталоге libs. Это все, что нужно Eclipse.

Импорт в Eclipse

Вот тут-то и начинается настоящая польза. После того, как вы создали каталог libs на шаге gradle выше, вы заметите, что там тоже есть папки. Эти новые папки представляют собой развернутые зависимости AAR из вашего файла build.gradle.

Теперь самое интересное заключается в том, что когда вы импортируете свой существующий проект Android в Eclipse, он также обнаружит взорванные папки AAR как проекты, которые он также может импортировать!

1. Импортируйте эти папки в каталог libs вашего проекта, не импортируйте папки сборки, они создаются Gradle

2. Убедитесь, что вы выполнили Проект -> Очистить для всех добавленных вами проектов AAR. В рабочей области убедитесь, что каждый разнесенный проект AAR имеет следующее в project.properties:

target=android-<YOUR INSTALLED SKD VERSION GOES HERE>
android.library=true

3. Теперь в свой основной проект Android вы можете просто добавить ссылки на библиотеки с помощью ADT или просто отредактировать файл project.properties и добавить

android.libraries.reference.1=libs/someExplodedAAR/

4. Теперь вы можете щелкнуть правой кнопкой мыши основной проект Android и выбрать Запустить от имени -> Приложение Android.

Но что это вообще значит?

  1. Ну, это означает, что вам не нужен исходный код для любой из ваших зависимостей Android AAR Gradle, чтобы ссылаться как на его классы, так и на ресурсы в Eclipse.

  2. Приведенный выше скрипт сборки gradle берет файл AAR и подготавливает его для использования в Eclipse. Как только вы добавите его в свое рабочее пространство, вы готовы просто сосредоточиться на своем основном проекте Android.

  3. Теперь вы можете отлаживать и разрабатывать с помощью Eclipse и развертывать с помощью ADT с зависимостями AAR, которые должным образом объединены в APK. Когда вам нужно сделать некоторые конкретные сборки, вы можете использовать gradle.

person JavaJedi    schedule 20.04.2014
comment
JavaJedi, спасибо за ваш пост. Вы нашли способ сделать исходный код зависимостей jar доступными для отладки в Eclipse? - person CannyDuck; 10.05.2014
comment
@JavaJedi Не могли бы вы скопировать уценку в README по адресу github.com/Nodeclipse/nodeclipse-1/blob/master/ - person Paul Verest; 30.05.2014
comment
Имеет смысл добавить это решение во встроенную справку github.com/Nodeclipse/nodeclipse-1/blob/master/ - person Paul Verest; 30.05.2014
comment
Этот метод великолепен, и я очень рад, что смог немного упростить с его помощью свой репозиторий. Я столкнулся с проблемой наличия файлов jar, уже существующих в папке /libs моего проекта. Копирование файла на себя приводило к 0-байтовому файлу. Перемещение этих банок в каталог /libraries, чтобы они могли быть перемещены в libs задачей, решило проблему. - person MeanderingCode; 17.09.2014
comment
@JavaJedi: Привет, я не могу заставить твое решение работать. Не могли бы вы проверить: stackoverflow. com/questions/28780426/? - person Jim; 28.02.2015
comment
Привет, у меня возникла проблема с этим кодом. Я пытаюсь использовать его в своем библиотечном проекте, но получаю сообщение Невозможно изменить конфигурацию ':libprojectname:compile' после того, как он был разрешен. - person Ika; 17.05.2015
comment
Кажется, проблема, с которой я столкнулся, была результатом того, что код не был размещен последним. Теперь я столкнулся с другой проблемой, когда `configuration.compile.filter {it.name.endsWith 'jar'}.each {File file -> moveJarIntoLibs(file)}` не удается, поскольку он не может найти библиотеку поддержки. ‹code›Ошибка: не удалось найти com.android.support:support-v13:22.1.1. Поиск выполнялся в следующих местах: файл:/C:/Users/barmei/.m2/repository/com/android/support/support-v13/22.1.1/support-v13-22.1.1.pom файл:/C:/ Пользователи/barmei/.m2/repository/com/android/support/support-v13/22.1.1/support-v13-22.1.1.jar‹code› .. - person Ika; 17.05.2015
comment
Мне удалось решить проблему с библиотекой поддержки [см.]: (stackoverflow.com/questions/30287022/) - person Ika; 18.05.2015
comment
Отличный ответ, в качестве обновления, toolTestCompile был изменен на androidTestCompile : method-instrument" title="Ошибка Android при сборке импортированного модуля Gradle не удалось найти инструмент метода"> stackoverflow.com/questions/25067325/ - person TheFuquan; 04.06.2015

Наконец я нашел решение, которое работает для меня. Эта задача копирует зависимости в папку проектов libs.

task copyDependencies(type: Copy) 
{
    description = 'Copy depencies to libs. Useful for Eclipse'
    libDir = new File(project.projectDir, '/libs')
    println libDir
    println 'Adding dependencies from compile configuration'
    for(file in configurations.compile) 
    {
        println 'Added ' + file
        copy 
        {
            from file
            into libDir
        }
    }
    println 'Adding dependencies from releaseCompile configuration'
    for(file in configurations.releaseCompile)
    {
        println 'Added ' + file
        copy
        {
            from file
            into libDir
        }
    }
    println 'Adding dependencies from debugCompile configuration'
    for(file in configurations.debugCompile)
    {
        println 'Added ' + file
        copy
        {
            from file
            into libDir
        }
    }

    println 'Adding dependencies from instrumentTestCompile configuration'
    for(file in configurations.instrumentTestCompile)
    {
        println 'Added ' + file
        copy
        {
            from file
            into libDir
        }
    }
}
person Rafael    schedule 26.05.2013
comment
Является ли это самым элегантным способом заставить проект распознавать новые зависимости? Или это было решено?? - person Erik; 14.11.2013

Следующая задача Gradle просто объединяет зависимости Gradle в путь к классам eclipse. Добавьте его в build.gradle и вызовите с помощью gradle gradleDep2EclipseClasspath.

  import groovy.xml.StreamingMarkupBuilder
  task gradleDep2EclipseClasspath() {
     description "Merge gradle dependencies into the eclipse class path"

     def files = ["compile", "releaseCompile", "debugCompile", "instrumentTestCompile"]
       .collect {project.configurations[it].files}
       .inject([] as Set) {result, files -> result + files}
       .asList()
       .unique()
       .grep {! [email protected]().contains("android-support")}

      def classpath = new XmlParser().parse(file(".classpath"))
      def libs = classpath.grep {it.'@gradle-dependency' == "true"}
      libs.each {classpath.remove(it)}

      files.collect {file ->
         new Node(null, "classpathentry", [
           "path": file.toString(),
           "kind": "lib",
           "exported": "true",
           "gradle-dependency": "true"
         ])
      }.each {classpath.append(it)}

      file(".classpath").withWriter {writer ->
         writer << new StreamingMarkupBuilder().bind { mkp.xmlDeclaration() }
         def printer = new XmlNodePrinter(new PrintWriter(writer))
         printer.print(classpath)
      }
   }
person gubaer    schedule 31.01.2014
comment
Это очень полезно и естественно, большое спасибо! В качестве примечания, эти зависимости не имеют прикрепленных источников. Я использовал marketplace.eclipse.org/content/java-source-attacher для добавить недостающие источники. Также было бы трудно исключить AAR из этого списка? - person afrish; 07.02.2015

Благодаря решению JavaJedi я создал еще один, используя аннотации ввода/вывода Gradle. Он основан на тех же принципах, но более универсален в использовании (например, вы можете легко определить новые задачи типа CopyJars или ExtractAars) и позволяет Gradle решать, нужно ли копирование файлов или нет.

person Orzech    schedule 11.09.2014

Вот мое решение, основанное на всех предыдущих решениях от @JavaJedi и @gubaer.

Шаг 1

Добавьте задачу copyAars в build.gradle. Он распаковывает и копирует зависимости AAR в специальную папку «deps», а не в «libs», чтобы избежать конфликтов с Android Studio и/или другими плагинами и задачами Gradle. После этого все разнесенные AAR должны быть вручную импортированы как проекты библиотеки Android и добавлены в качестве зависимостей к основному проекту в Eclipse. Это модифицированное решение от @JavaJedi.

task copyAars << {
    configurations.compile.filter { it.name.endsWith 'aar' }.each { File file -> copyAndRenameAar(file) }
}

void copyAndRenameAar(File file) {
    println 'Added aar ' + file
    def baseFilename = file.name.lastIndexOf('.').with { it != -1 ? file.name[0..<it] : file.name }

    // directory excluding the classes.jar
    copy {
        from zipTree(file)
        exclude 'classes.jar'
        into "deps/aars/exploded/" + baseFilename
    }

    // Copies the classes.jar into the libs directory of the expoded AAR.
    // In Eclipse you can then import this exploded aar as an Android project
    // and then reference not only the classes but also the android resources
    copy {
        from zipTree(file)
        include 'classes.jar'
        into "deps/aars/exploded/" + baseFilename + "/libs"
        rename { String fileName -> fileName.replace('classes.jar', baseFilename + '.jar') }
    }
}

Шаг 2

Добавьте задачу eclipseClasspath в build.gradle. Зависимости JAR добавляются другим способом. Они фильтруются и добавляются непосредственно в файл .classpath, поэтому автоматически становятся доступными в основном проекте Eclipse. Это модифицированное решение от @gubaer. Он включает только JAR-файлы, исключая AAR-файлы и только из «компилируемой» конфигурации, но вы можете легко добавить больше конфигураций.

task eclipseClasspath << {
    def classpath = new XmlParser().parse(file(".classpath"))
    def libs = classpath.grep { it.'@gradle-dependency' == "true" }
    libs.each { classpath.remove(it) }

    configurations.compile.filter { it.name.endsWith 'jar' }
    .collect { file ->
        new Node(null, "classpathentry", [
            "path": file.toString(),
            "kind": "lib",
            "exported": "true",
            "gradle-dependency": "true"
        ])
    }
    .each { classpath.append(it) }

    file(".classpath").withWriter { writer ->
        writer << new groovy.xml.StreamingMarkupBuilder().bind { mkp.xmlDeclaration() }
        def printer = new XmlNodePrinter(new PrintWriter(writer))
        printer.print(classpath)
    }
}

Шаг 3

Установите http://marketplace.eclipse.org/content/java-source-attacher плагин в Eclipse. После этого вы сможете щелкнуть правой кнопкой мыши на каждом JAR и выбрать «Прикрепить исходный код Java». По моему опыту, для зависимостей Gradle это работает в 99% случаев.

person afrish    schedule 09.02.2015