如何构建包含不同compileSdkVersion、targetSdkVersion和minSdkVersion模块的Android Gradle项目?

6

我的Android库项目由四个模块组成:

  • project
    • base
    • factory
    • v14
    • v18

以下是IntelliJ上这个设置的截图:

modules

我的模块利用非常具体的Android SDK级别设置:

  • base
    • compileSdkVersion 19
    • minSdkVersion 14
    • targetSdkVersion 19
  • factory
    • compileSdkVersion 19
    • minSdkVersion 14
    • targetSdkVersion 19
  • v14
    • compileSdkVersion 17
    • minSdkVersion 14
    • targetSdkVersion 17
  • v18
    • compileSdkVersion 18
    • minSdkVersion 18
    • targetSdkVersion 18

随着新版本的Android发布,基础模块和工厂模块可以跟随其compileSdkVersiontargetSdkVersion级别进行更改。但是,v14和v18绝对不能这样做。

我的模块之间有非常具体的依赖关系:

  • base
    • 不依赖于任何其他模块
  • factory
    • 依赖于base、v14和v18
  • v14
    • 依赖于base
  • v18
    • 依赖于base

因此,当我构建我的项目时,我会收到此错误:

Error:Gradle: Execution failed for task ':v14:processReleaseManifest'.
> Manifest merging failed. See console for more info.

当使用终端构建时,使用./gradlew build --stacktrace命令,我会得到更多的信息:

:v14:processReleaseManifest
[/blahblah/project/v14/build/exploded-aar/blahblah/base/unspecified/AndroidManifest.xml:2] Main manifest has <uses-sdk android:targetSdkVersion='17'> but library uses targetSdkVersion='19'
:v14:processReleaseManifest FAILED

以下是我的v14 AndroidManifest.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.example.v14">

    <application />

</manifest>

(我的基本AndroidManifest.xml文件几乎完全相同)

<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.example">

    <application />

</manifest>

这个错误对我来说毫无意义。首先,我在我的四个不同的AndroidManifest.xml文件中没有指定版本级别(而是让这些值通过我的四个不同的build.gradle文件继承)。
其次,我没有一个“主清单”。基本模块可能是我最接近的东西,所以v14模块如何成为“主清单”我觉得非常令人困惑。
最后,如果这个项目设置不可行,那么我很震惊。这个模块配置在类似Eclipse的项目中绝对是微不足道的。这就是我几个月来一直在构建库的方式。
顺便说一句,我的最终目标是将所有内容编译成一个单独的.jar文件,我的当前Eclipse-style项目可以做到这一点。只是我正在尝试完全迁移到gradle,不要被留在沉船上……
有什么想法吗?如果必要的话,我可以发布我的各种gradle文件(build.gradlesettings.gradle……)。只是想避免完全超载这篇文章。
编辑(2014年5月27日)
在这篇文章的开头添加了我的模块配置的截图。

2
最好的情况是,这会影响您的构建目标(即compileSdkVersion)。除非您在设备制造商工作(从而可以精确了解这些内部类对于您的设备的情况),否则请不要干扰它们。关于您的问题,我认为他们正在强制执行compileSdkVersion兼容性,因为AAR是编译的,而不是基于源代码的库项目。从错误的exploded-aar来看,感觉您的模块是库项目,这可能会在最终获得单个JAR时给您带来问题。 - CommonsWare
是的,我理解你的担忧!但实际上,我的实现在我测试过的所有设备上(大约10个不同制造商和类型的设备)都非常出色。但好吧,根据这次交谈,看起来我可能无法将这个库推进到gradle。不过我会继续调查,感谢你的时间。 - Charles Madere
你的意思是模块等同于口味吗? - maclir
@maclir,我刚刚在我的问题中添加了一张截图,这有帮助吗? - Charles Madere
如果你最终只有一个包含所有类的单个jar文件,可以被依赖于你的库的应用程序访问。那么为什么还要费心去创建单独的模块呢?这只是为了更容易地进行维护吗?或者你的目标是根据minSdk属性使应用程序选择正确的类? - Damian Petla
显示剩余2条评论
1个回答

0
如果您正在根据Gradle插件用户指南使用flavors:

defaultConfig为所有flavor提供基本配置,每个flavor都可以覆盖任何值。

例如,您可以在build.gradle文件中设置以下内容:
    android {

    ...

        defaultConfig {
            ...
            compileSdkVersion 19
            minSdkVersion 14
            targetSdkVersion 19
        }

        productFlavors {
            base {
                compileSdkVersion 19
                minSdkVersion 14
                targetSdkVersion 19
            }

            factory {
                compileSdkVersion 19
                minSdkVersion 14
                targetSdkVersion 19
            }

            v14 {
                compileSdkVersion 17
                minSdkVersion 14
                targetSdkVersion 17
            }

            v18 {
                compileSdkVersion 18
                minSdkVersion 18
                targetSdkVersion 18
            }
        }
    }

此外,在清单文件中也不需要设置包名。您可以按照以下方式进行设置:
android {
    ...

    productFlavors {
        base {
            packageName "com.example"
            ...
        }

        v14 {
            packageName "com.example.v14"
            ...
        }
        ...
    }
}

ScootrNova提到他在最后只生成一个JAR文件。但是使用flavours会产生多个输出。 - Damian Petla

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接