首页 文章

通过gradle将依赖项添加到android项目中的eclipse

提问于
浏览
10

我有一个问题,通过gradle自动添加依赖项来eclipse安卓项目 . 我对gradle只有一点点经验 . 直到现在我已经用gradle构建了两个java项目 . 一个jar和一个可执行jar . 这没有问题 . 我使用eclipse插件生成eclipse项目并将依赖项添加到构建路径 . 我向gradle脚本添加了新的依赖项,使用gradle eclipse启动gradle,更新我的项目,并且构建路径中存在依赖项,我可以使用它们 . 这是该脚本的重要部分 .

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

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

所以,现在我尝试结合android插件 . 这是我的洞gradle脚本 .

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插件不兼容的错误 . 然后我找到了一个解决方案,将jar自动复制到项目的lib文件夹中 .

def libDir = file('libs')

task copyLibs(type: Copy) {

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

但是这个任务也需要配置.runtime的java插件 . 我需要android插件来创建apk文件,所以它不是一个删除android插件的解决方案 . 有人知道是否有可能将依赖项添加到与android插件兼容的ecipse项目中的构建路径或lib文件夹中?

编辑:我的一个想法是将java-plugin放到eclipse-plugin中,这样它只会在应用eclipse插件时应用 . 像这样的东西:

apply plugin: 'eclipse'

eclipse{
    apply plugin: 'java'
}

但我仍然得到java和android插件不兼容的错误 . 也许我理解gradle错误,但通常只有当我启动eclipse插件而不是android插件时才应用java插件 . 我担心我对gradle的理解和经验不足以解决这个问题,或者理解为什么不可能 .

5 回答

  • 12

    我的解决方案基于Rafael's,因为它将依赖关系复制到仅由Android使用的libs目录 . 但是我进一步完全爆炸引用的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"

    您应该在libs目录中找到所有依赖项和爆炸AAR . 这是Eclipse应该需要的全部内容 .

    在Eclipse中导入

    现在,这是真正的利益开始的地方 . 从上面的gradle步骤生成libs目录后,您会发现其中也有文件夹 . 这些新文件夹是build.gradle文件中爆炸的AAR依赖项 .

    现在最酷的部分是,当您将现有的Android项目导入Eclipse时,它还会将爆炸的AAR文件夹检测为它可以导入的项目!

    1. 在项目的 libs 目录下导入这些文件夹,由Gradle生成't import any ' build ' folders, they'

    2. 确保对已添加的所有AAR项目执行 Project -> Clean . 在工作区中检查每个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项目和 Run as -> Android Application .

    但这甚至意味着什么?

    • 这意味着您不需要任何Android AAR Gradle依赖项的源代码,以便在Eclipse中引用它的类和资源 .

    • 上面的gradle构建脚本获取AAR文件并准备在Eclipse中使用 . 将它添加到工作区后,您就可以专注于实际的主要Android项目了 .

    • 您现在可以使用Eclipse进行调试和开发,并使用ADT进行部署,并在APK中正确捆绑AAR依赖项 . 当你需要制作一些特定的版本时,你可以使用gradle .

  • 0

    最后,我找到了一个适合我的解决方案 . 此任务将依赖项复制到项目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
            }
        }
    }
    
  • 2

    以下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 {! it.@path.toString().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)
          }
       }
    
  • 4

    感谢JavaJedi's解决方案,我使用Gradle的输入/输出注释创建了another one . 它基于相同的原则,但更多一般使用(例如,您可以轻松定义 CopyJarsExtractAars 类型的新任务)并允许Gradle决定是否需要文件复制 .

  • 0

    以下是基于@JavaJedi和@gubaer之前所有解决方案的解决方案 .

    Step 1

    copyAars 任务添加到build.gradle . 它将AAR依赖项解压缩并复制到特殊文件夹"deps",而不是"libs",以避免与Android Studio和/或其他Gradle插件和任务发生冲突 . 之后,所有爆炸的AAR都应手动导入为Android Library项目,并作为依赖项添加到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') }
        }
    }
    

    Step 2

    eclipseClasspath 任务添加到build.gradle . JAR依赖项以不同的方式添加 . 它们被过滤并直接添加到.classpath文件中,因此它们可以在Eclipse主项目中自动使用 . 这是@gubaer的修改后的解决方案 . 它仅包含JAR,不包括AAR,仅包含"compile"配置,但您可以轻松添加更多配置 .

    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)
        }
    }
    

    Step 3

    在Eclipse中安装http://marketplace.eclipse.org/content/java-source-attacher插件 . 之后,您将能够右键单击每个JAR并选择"Attach Java Source" . 对于Gradle依赖项,根据我的经验,99%的时间都可以使用 .

相关问题