在android项目中通过gradle向eclipse添加依赖项

在android项目中通过gradle向eclipse添加依赖项,android,eclipse,gradle,Android,Eclipse,Gradle,我在通过gradle自动向EclipseAndroid项目添加依赖项时遇到问题。 我对格雷德尔只有一点经验。到目前为止,我已经用gradle构建了两个java项目。一个jar和一个可执行jar。这是没有问题的。 我已经使用eclipse插件来生成eclipse项目,并将依赖项添加到构建路径中。我向gradle脚本添加了新的依赖项,用gradleeclipse启动了gradle,更新了我的项目,这些依赖项存在于构建路径中,我可以使用它们。以下是该脚本的重要部分 apply plugin: 'jav

我在通过gradle自动向EclipseAndroid项目添加依赖项时遇到问题。 我对格雷德尔只有一点经验。到目前为止,我已经用gradle构建了两个java项目。一个jar和一个可执行jar。这是没有问题的。 我已经使用eclipse插件来生成eclipse项目,并将依赖项添加到构建路径中。我向gradle脚本添加了新的依赖项,用gradleeclipse启动了gradle,更新了我的项目,这些依赖项存在于构建路径中,我可以使用它们。以下是该脚本的重要部分

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

dependencies {
   compile 'commons-io:commons-io:2.4'
}
所以,现在我尝试将它与android插件结合使用。这是我的hole 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')
    }
}
如果我使用gradleeclipse,什么都不会发生。然后我发现java插件将依赖项添加到构建路径中。所以我补充说

apply plugin: 'java'
并得到了java插件与android插件不兼容的错误。 然后我找到了一个解决方案,可以将JAR自动复制到项目的lib文件夹中

def libDir = file('libs')

task copyLibs(type: Copy) {

    doFirst {
        libDir.mkdirs()
    }
    from configurations.runtime
    into libDir
}
但是这个任务也需要configurations.runtime的java插件。 我需要android插件来创建apk文件,所以它不是删除android插件的解决方案。 有人知道是否可以将依赖项添加到ecipse项目中与android插件兼容的构建路径或lib文件夹中吗

编辑: 我的一个想法是将java插件放在eclipse插件中,这样只有在应用eclipse插件时才会应用java插件。大概是这样的:

apply plugin: 'eclipse'

eclipse{
    apply plugin: 'java'
}
但是我仍然得到一个错误,java和android插件不兼容。
也许我对gradle的理解是错误的,但是通常java插件应该只在我启动eclipse插件时应用,而不是android插件。我担心我对gradle的理解和经验不足以解决这个问题,也不足以理解为什么不可能解决这个问题。

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

下面的gradle任务只是将gradle依赖项合并到eclipse类路径中。将它添加到
build.gradle
并使用
gradle-gradleDep2EclipseClasspath
调用它

import groovy.xml.StreamingMarkupBuilder
任务GradeDep2eClipseClassPath(){
描述“将渐变依赖项合并到eclipse类路径”
def files=[“compile”、“releaseCompile”、“debugCompile”、“instrumentTestCompile”]
.collect{project.configurations[it].files}
.inject([]设置为){result,files->result+files}
.asList()
.unique()
.grep{!it.@path.toString()包含(“android支持”)}
def classpath=new XmlParser().parse(文件(“.classpath”))
def libs=classpath.grep{it.@gradle dependency'==“true”}
libs.each{classpath.remove(it)}
files.collect{file->
新节点(空,“classpathentry”[
“路径”:file.toString(),
“种类”:“lib”,
“导出”:“真”,
“渐变依赖项”:“true”
])
}.each{classpath.append(it)}
文件(“.classpath”)。带writer{writer->
writer我的解决方案的基础是,它将依赖项复制到仅由Android使用的libs目录中。不过,我进一步将引用的AAR完全分解,以便在Eclipse中使用

渐变生成文件 在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')
        }
    }
}
3。现在,在主Android项目中,您可以使用ADT添加库引用,也可以编辑project.properties文件并添加

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

4.现在,您可以右键单击主Android项目,然后运行as->Android应用程序

但这到底意味着什么呢?
  • 这意味着您不需要任何Android AAR Gradle依赖项的源代码来引用Eclipse中的类和资源

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

  • 现在,您可以使用Eclipse进行调试和开发,并使用ADT进行部署,将AAR依赖项正确绑定到APK中


  • 多亏了我使用Gradle的输入/输出注释创建的解决方案。它基于相同的原则,但在使用中更加通用(例如,您可以轻松定义
    CopyJars
    ExtractAars
    类型的新任务)并允许Gradle决定是否需要复制文件。

    这是我基于@JavaJedi和@gubaer之前所有解决方案的解决方案

    步骤1

    copyars
    任务添加到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') }
        }
    }
    
    步骤3


    在Eclipse中安装插件。之后,您可以右键单击每个JAR并选择“附加Java源代码”。对于Gradle依赖项,在我的经验中,这在99%的时间内都有效。

    这是让项目识别新依赖项的最优雅的方式吗?还是已经解决了?JavaJedi,谢谢你的帖子。是否@JavaJedi可以请你将标记复制到自述文件中?将此解决方案添加到内置帮助中是有意义的这项技术是gre在,我真的很高兴能够用它简化我的存储库。我遇到了一个问题,jar文件已经存在于m的
    /libs
    文件夹中
    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') }
        }
    }
    
    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)
        }
    }