Android Gradle构建子项目

时间:2013-06-06 20:16:18

标签: android gradle facebook-android-sdk

我目前正在将我们的一个项目从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是一个图书馆项目,它应该能够单独构建和打包,这就是为什么它有自己的settings.gradle,据我所知,它似乎工作正常,我有它建设并且它发现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中构建时无关紧要。这可能是由于我直接引用ProjectB而不是通过ProjectBRoot / gradle.build引用的面孔,但我尝试了它,但它也没有用。有人可以帮助我,我已经查看了文档,它没有谈论有多个项目有自己的settings.gradle文件,我认为这是让我搞砸的事情。

更新

所以我按照Xav的回答,我现在能够使用命令行构建,但我无法使用android studio导入/构建。我知道问题仍然是facebook项目。我得到的错误是它无法配置ProjectB。

 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中

5 个答案:

答案 0 :(得分:94)

settings.gradle必须定义所有模块。它不会加载树中的其他settings.gradle来加载更多模块。

你必须要么

  1. 在顶级settings.gradle中为facebook SDK定义模块。是的,它与其他settings.gradle是多余的。

  2. 以某种方式发布项目B(以及它的依赖关系,所以在这种情况下是facebook SDK库),某处(例如公司工件库)并从项目A访问它。

  3. 虽然#1更好,但它使ProjectB - > Facebook依赖性很棘手,因为路径会有所不同,具体取决于使用的settings.gradle。解决此问题的一种方法是将模块名称/路径从其在磁盘上的实际位置拆分。这是在settings.gradle文件中完成的。

    在顶级settings.gradle文件中,执行

    include 'facebook-sdk'
    project(':facebook-sdk').projectDir = new File('Libraries/ProjectBRoot/Libraries/FacebookSDK/facebook')
    

    在项目B内的setting.gradle文件中,使用不同的相对路径执行相同操作:

    include 'facebook-sdk'
    project(':facebook-sdk').projectDir = new File('Libraries/FacebookSDK/facebook')
    

    这使得两个项目设置都定义了位于磁盘上相同绝对位置的相同“facebook-sdk”模块。

    依赖于此模块的所有项目都应该将依赖项声明为

    compile project(':facebook-sdk') 
    

答案 1 :(得分:5)

这不是您正在寻找的答案,但是......

我花了大约4天时间尝试将我复杂的项目结构(实际上与你的实际情况很相似)迁移到gradle中。最后,我放弃了整个子项目的概念(因为在我的情况下,它只是没有用),我选择使用本地maven存储库方法,如本文所述:http://www.flexlabs.org/2013/06/using-local-aar-android-library-packages-in-gradle-builds

因此,在我的具有子项目的图书馆项目中,我基本上为每个项目创建了完整的库项目,然后我使用上面的链接将这些项目发布到maven本地存储库。然后在父项目中,我删除了对子项目的任何引用,在依赖项中,我只引用了已发布的库。然后在我的主项目中,删除了对子项目的所有引用,并引用了我的库的已发布的maven本地版本。

最后,一切都运作良好,但确实需要一些时间来转换所有内容。我有大约6个子项目的图书馆项目,子项目等,现在一切正常。

我不喜欢像Gradle和Maven这样的系统,他们真的希望你改变你的代码/项目结构。因此,如果您要迁移到Gradle而不是从Gradle开始,那么这个过程可能非常令人沮丧。一旦你搞清楚了,下一次就容易了;)

答案 2 :(得分:4)

我只是将这些库的应用程序放在同一级别。您仍然可以基于build.gradle文件构建和打包每个库。我可能会遗漏一些东西,但结构并不像build.gradle文件那样重要。即使它们处于相同的文件夹级别,你仍然可以让projectB依赖于Facebook。

答案 3 :(得分:2)

出现同样的问题,就我而言,我忘了在settings.gradle中添加项目。在那之后,它工作了

答案 4 :(得分:1)

我终于设法构建项目(没有gradle错误)。来自Xavier的回答非常有帮助。

我花了差不多3天的时间来设置我的项目,我知道我非常接近finsihed,但是在gradle构建过程的最后一步(dexDebug)我有意想不到的顶级异常。

我的项目设置与Stoyan非常相似,但是我有多个android-library项目引用了android-support库。我建议如果你有编译你的顶级根项目的问题(错误说支持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)'

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

// top root settings.gradle

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