Android Gradle使用子项目进行构build
我目前正在将我们的一个项目从maven转换为Gradle。 文件夹结构如下:
gitRoot settings.gradle build.gradle ProjectA build.gradle src/main/java Libraries SomeLib (git submodule) ProjectBRoot (git submodule) settings.gradle build.gradle ProjectB build.gradle src/main/java Libraries FacebookSDK/facebook build.gradle src
所以看起来很复杂。 但是,这个想法是ProjectB是一个图书馆项目,它应该能够分别build立和打包,这就是为什么它有自己的settings.gradle和据我所知,似乎工作正常,我build设它的发现Facebook就好了。
ProjectB / build.gradle包含这一行
compile project(':libraries:facebook-android-sdk:facebook')
ProjectBRoot / settings.gradle包含这一行
include ':ProjectB', ':libraries:facebook-android-sdk:facebook'
gitRoot / settings.gradle包含这一行
include ':ProjectA', ':Libraries:ProjectBRoot:ProjectB'
ProjectA / build.gradle包含这一行
compile project(':Libraries:ProjectBRoot:ProjectB')
当我运行生成我得到这个错误
The TaskContainer.add() method has been deprecated and is scheduled to be removed in Gradle 2.0. Please use the create() method instead. FAILURE: Build failed with an exception. * Where: Build file '/gitRoot/Libraries/ProjectBRoot/ProjectB/build.gradle' line: 17 * What went wrong: A problem occurred evaluating project ':Libraries:ProjectBRoot:ProjectB'. > Project with path ':libraries:facebook-android-sdk:facebook' could not be found in project ':Libraries:ProjectBRoot:ProjectB'. * Try: Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. BUILD FAILED Total time: 4.652 secs
所以我猜猜是什么错误的是,Facebook不在ProjectB的直接子文件夹中…但在ProjectBRoot中构build时并不重要。 这可能是由于我直接引用ProjectB而不是通过ProjectBRoot / gradle.build引起的,但是我尝试了这种方式,但是也没有奏效。 有人可以帮我,我已经浏览了文档,并没有谈到多个项目有自己的settings.gradle文件,我认为这是让我搞砸的东西。
更新:
所以我遵循Xav的答案,现在我可以用命令行来构build,但是我不能用android studio导入/构build。 我知道问题仍然与Facebook项目。 我得到的错误是它不能configurationProjectB。
Gradle: A problem occurred configuring project ':ProjectA'. > Failed to notify project evaluation listener. > A problem occurred configuring project ':Libraries:ProjectBRoot:ProjectB'. > Failed to notify project evaluation listener. > Configuration with name 'default' not found.
错误是由行引起的
compile project(':facebook-sdk')
在ProjectB / build.gradle中
settings.gradle必须定义所有的模块。 它不会加载树中find的其他settings.gradle来加载更多的模块。
你必须要么
-
在顶级settings.gradle中为facebook SDK定义一个模块。 是的,与其他settings.gradle是多余的。
-
以某种方式发布项目B(以及它的依赖关系,所以在这个例子中是facebook SDK库),在某个地方(例如一个公司工件库)发布项目B并从项目A访问它。
虽然#1更好,它使得ProjectB – > Facebook的依赖性棘手,因为path将有所不同,取决于使用的设置。 解决这个问题的一种方法是将模块名称/path从磁盘上的实际位置分开。 这是在settings.gradle文件中完成的。
在最高级别的settings.gradle文件中,执行
include 'facebook-sdk' project(':facebook-sdk').projectDir = new File('Libraries/ProjectBRoot/Libraries/FacebookSDK/facebook')
在Project B中的setting.gradle文件中,执行相同的相对path:
include 'facebook-sdk' project(':facebook-sdk').projectDir = new File('Libraries/FacebookSDK/facebook')
这使得两个项目设置都定义了位于磁盘上相同绝对位置的相同'facebook-sdk'模块。
所有依赖于这个模块的项目都应该声明依赖关系
compile project(':facebook-sdk')
这不是你正在寻找的答案,但是…
我花了大约4天的时间尝试将我的复杂项目结构(与您的实际情况非常类似)迁移到gradle中。 最后,我放弃了整个子项目的概念(因为在我的情况下,它只是不工作),我select使用本地Maven存储库的方法,如本文所述: http://www.flexlabs .ORG / 2013/06 /使用本地-AAR-Android的库封装function于gradle这个-build立
所以,在我的库项目有子项目,我基本上为每个项目创build完整的库项目,然后我使用上面的链接发布到maven本地存储库。 然后在父项目中,我删除了对子项目的任何引用,并且在依赖关系中,我只引用了已发布的库。 然后在我的主项目中,我删除了对子项目的所有引用,并引用了我的库的已发布maven本地版本。
最后,这一切都运行得很好,但需要一些时间来转换一切。 我有大约6个子项目的图书馆项目,那个子项目等,现在一切正常。
我不喜欢像Gradle和Maven这样的系统,他们真的希望你改变你的代码/项目结构。 所以,如果你正在从Gradle开始迁移到Gradle,那么这个过程会非常令人沮丧。 一旦你知道了,下一次更容易;)
我只是在同一级别的图书馆的应用程序。 您仍然可以基于build.gradle文件构build和打包每个库。 我可能会错过一些东西,但是这个结构并不像build.gradle文件中那样重要。 即使它们位于相同的文件夹级别,您仍然可以使用projectB依赖于Facebook。
我终于设法build立了这个项目(没有gradle错误)。 来自泽维尔的回答非常有帮助。
我花了差不多3天的时间来设置我的项目,我知道我已经非常接近了,但是在gradle构build过程的最后一步(dexDebug),我有意外的顶级exception(EXCLUSPEDED TOP-LEVEL EXCEPTION)。
我的项目设置非常类似于Stoyan的,但是我有多个引用android-support库的android-library项目。 我build议,如果你有编译你的最高根项目(错误说支持android已被添加)的问题比你需要将jar移动到单独的android库项目(分解/分离成独立的实例)。
例
--| ProjectARoot --| ProjectA (where main/java etc are) --| build.gradle --| settings.gradle --| libraries --| ProjectBRoot --| settings.gradle --| ProjectB --| libraries --| android-supports (android lib project) --| libs --| android-support-v4.jar --| android-support-v13.jar --| build.gradle --| libA --| build.gradle (referencing android-supports)'
示例构build脚本libA引用android支持项目
buildscript { repositories { maven { url 'http://repo1.maven.org/maven2' } } dependencies { classpath 'com.android.tools.build:gradle:0.4' } } apply plugin: 'android-library' dependencies { compile project(':android-support') } android { compileSdkVersion 17 buildToolsVersion "17.0.0" defaultConfig { minSdkVersion 7 targetSdkVersion 17 } }
//顶部的根设置
include 'ProjectB', 'android-support', ':ProjectA' (notice Project B is first than android-support and lastly Project A) project(':android-support').projectDir = new File('libraries/ProjectBRoot/libraries/android-support') project(':ProjectB').projectDir = new File('libraries/ProjectBRoot/ProjectB')
目前当我运行gradle构build时,我得到这个错误
:ProjectA:dexDebug UNEXPECTED TOP-LEVEL EXCEPTION: java.lang.IllegalArgumentException: already added: Landroid/support/v4/accessibilityservice/AccessibilityServiceInfoCompat; at com.android.dx.dex.file.ClassDefsSection.add(ClassDefsSection.java:123) at com.android.dx.dex.file.DexFile.add(DexFile.java:163) at com.android.dx.command.dexer.Main.processClass(Main.java:490) at com.android.dx.command.dexer.Main.processFileBytes(Main.java:459) at com.android.dx.command.dexer.Main.access$400(Main.java:67) at com.android.dx.command.dexer.Main$1.processFileBytes(Main.java:398) at com.android.dx.cf.direct.ClassPathOpener.processArchive(ClassPathOpener.java:245) at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:131) at com.android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.java:109) at com.android.dx.command.dexer.Main.processOne(Main.java:422) at com.android.dx.command.dexer.Main.processAllFiles(Main.java:333) at com.android.dx.command.dexer.Main.run(Main.java:209) at com.android.dx.command.dexer.Main.main(Main.java:174) at com.android.dx.command.Main.main(Main.java:91) 1 error; aborting :ProjectA:dexDebug FAILED
有同样的问题,在我的情况下,我忘了在settings.gradle
添加项目。 之后,它的工作