Android Gradle创建多项目Jar

Android Gradle创建多项目Jar,android,jar,dependencies,gradle,task,Android,Jar,Dependencies,Gradle,Task,所以,从他们成立之初起,我就一直在Gradle和Android Studio中演奏。然而,我发现自己的头撞在墙上的次数远远超过了它的价值 我花了一天半的时间试图解决目前的困境 在我工作的地方,我们使用了很多共享库项目。这意味着,与Gradle的原生假设不同,我的项目并不都嵌套在一个父项目下。(但这不是我的问题)我已经实现了这一点 在我们的项目完成并准备就绪后,有人要求它为当前的项目基础架构创建一个SDK供外部使用。现在在旧的IntelliJ中,我只需生成一些Javadoc并创建一个包含所有依赖项

所以,从他们成立之初起,我就一直在Gradle和Android Studio中演奏。然而,我发现自己的头撞在墙上的次数远远超过了它的价值

我花了一天半的时间试图解决目前的困境

在我工作的地方,我们使用了很多共享库项目。这意味着,与Gradle的原生假设不同,我的项目并不都嵌套在一个父项目下。(但这不是我的问题)我已经实现了这一点

在我们的项目完成并准备就绪后,有人要求它为当前的项目基础架构创建一个SDK供外部使用。现在在旧的IntelliJ中,我只需生成一些Javadoc并创建一个包含所有依赖项的工件,然后再创建一个不包含依赖项jar的工件,并分别命名它们非常高兴

然而,在Gradle,这似乎是非常困难的,甚至可能是不受支持的,我找不到任何其他人做过这件事。经过10个多小时的谷歌搜索和反复试验,我最终决定制作一个演示项目,以准确地展示我在做什么和我试图完成什么

我需要做几件事

  • 生成一个包含所有模块依赖代码和依赖Jar文件的Jar文件
  • 生成一个包含所有模块依赖代码和零依赖Jar文件的Jar文件
  • 生成一个AAR文件,其中包括所有模块依赖代码和依赖Jar文件,以及启动活动所需的资源(如果他们想使用它)
  • 生成一个AAR文件,其中包括所有模块依赖代码和ZERO Jar文件,以及启动活动所需的资源(如果他们想使用它)
  • 所以这就是我的问题所在。当使用(type:Jar)运行任务时,每个模块都只生成自己的代码。我设法让依赖的Jar文件在一次编译中编译,但是没有常规的源代码,但我从来没有能够让模块的源代码包含在Jar文件中,这是我目前最大的障碍

    下面是我在没有完成这个简单任务的情况下尝试过的任务列表

        evaluationDependsOn(':dependencyModule')
    
    
    task myJar(type: Jar){
        appendix = 'myJar'
        from android.sourceSets.main.allSource.files
    }
    
    task uberJar (type: Jar){
        from(configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }) {
            exclude "META-INF/*.SF"
            exclude "META-INF/*.DSA"
            exclude "META-INF/*.RSA"
        }
    }
    
    task fatJar(type: Jar, dependsOn: 'compileJava') {
        from {
            sourceSets.main.output.classesDir
        }
    
        // Add all dependencies except for android.jar to the fat jar
        from {
            configurations.compile.findAll {
                it.getName() != 'android.jar'
            }.collect {
                it.isDirectory() ? it : zipTree(it)
            }
        }
    
        archiveName = 'fatJar.jar'
    }
    
    task jarFat(type: Jar) {
        appendix = "fat"
        from android.sourceSets.main.java
        from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
    }
    
    task sourcesJar(type: Jar) {
        from android.sourceSets.main.allSource
        classifier = 'sources'
    }
    
    task clearJar(type: Delete) {
        delete 'build/libs/myCompiledLibrary.jar'
    }
    
    task makeJar(type: Copy) {
        from('build/bundles/release/')
        into('build/libs/')
        include('classes.jar')
        rename ('classes.jar', 'myCompiledLibrary.jar')
    }
    
    makeJar.dependsOn(clearJar, build)
    
    task jar(type: Jar) {
        from android.sourceSets.main.allJava
    }
    
    task deployJar(type: Jar, dependsOn: jar) {
        baseName = project.name + '-deploy'
        deps = configurations.runtime + configurations.archives.allArtifactFiles
        depClasses = { deps.collect { it.isDirectory() ? it : zipTree(it) } }
        from(depClasses) {
            exclude 'META-INF/MANIFEST.MF'
        }
    }
    
    task modelJar(type: Jar) {
        from sourceSets.main.output
    }
    task jarWithDependency(type: Jar){
        from android.sourceSets.main.classesDir
        from {configurations.compile.collect {zipTree(it)}}
    }
    
    task androidJavadocs(type: Javadoc) {
        source = android.sourceSets.main.allJava
    }
    
    还没有什么能完成这项工作。任何帮助都将不胜感激!! 提前感谢您抽出时间来看这篇文章。 如果有人喜欢的话,我有一个完整的示例项目,但是我看不到上传的选项,所以是我构建的演示项目的链接。它非常小,而且很容易遵循。基本上每个项目都有一个类或方法


    使用
    应用程序
    插件,您只需调用“distZip”即可获得包含所有库的zip。默认情况下,您将获得一个包含批处理文件和shell脚本的
    bin
    目录来运行程序,以及一个包含所有jar文件的
    lib
    目录

    您可能希望更新清单以包含所有必要的库,如以下所示(我还有其他的东西在我的清单中)

    EDIT我删除了对“project”的引用,因为在本例中不需要它

     jar.doFirst
     {
         // aggregate all the jars needed at runtime into a local variable (array)
         def manifestClasspath = configurations.runtime.collect { it.name }
    
         // remove duplicate jar names, and join the array into a single string
         manifestClasspath = manifestClasspath.unique().join(" ")
    
         // set manifest attributes - mainClassName must be set before it is used here
         manifest.attributes.put("Main-Class", mainClassName)
         manifest.attributes.put("Class-Path", manifestClasspath)
     }
    
    我不是Android开发者,所以你必须为AAR的东西添加一些额外的代码。

    作者更新。 随着时间的推移,我了解到最佳实践是允许依赖关系管理工具完成它们的工作,而不是试图将这些文件打包成这样

    您可以创建fat JAR和fat aar文件,有一些插件可以提供帮助,但这是有漏洞的,不允许用户正确排除嵌套在编译产品中的传递项。排除是为了让maven server pom文件包含或排除依赖项文件

    因此,使用Maven Repo服务器是管理此问题的最佳方法,因为FAT编译器插件不可靠,并且每次升级都会中断,更重要的是,它限制了用户在转换时排除“部分而非全部”的能力


    因此,如果你能避免这种情况并按照我推荐的正确方式来做,请不要这样做。我会留下这篇文章,以防其他人也走上这条不好的道路,并希望你转向依赖关系管理服务器的正确道路,这些服务器具有由pom文件管理的可传递依赖关系。

    嘿,谢谢你的回复。你能解释一下这是什么吗正在做什么?如果我使用第一行,我会得到一个错误,即在配置中找不到运行时。我不确定其他三行完成了什么。为了更清楚,编辑了示例。不要忘了在构建脚本的开头应用:应用程序。我可能错了,但我认为Android不会与应用程序一起工作tion插件。它只是失败了,说你不能将java插件应用到AndroidI上。我对应用语法不小心。你做到了吗?
    apply plugin:“application”
    Yes,它说“java插件已经应用了,但与Android插件不兼容”,在我删除它之前,它不会再构建。