简体   繁体   English

如何按buildType和风味拆分源

[英]How to split source by buildType AND flavor

I have an app with different package name for the buildTypes debug/release as well as for two productFlavors. 我有一个用于buildTypes调试/发行版以及两个productFlavor的具有不同包名称的应用程序。

The interesting part of my build.gradle looks like this: 我的build.gradle有趣的部分是这样的:

android {
    buildTypes {
        debug {
            packageNameSuffix ".debug"
        }

        release {
            signingConfig signingConfigs.release
        }
    }

    productFlavors {
        flavor1 {
            packageName "com.example.app.flavor1"
        }

        flavor2 {
            packageName "com.example.app.flavor2"
        }
}

So there are for package names: 因此,有包名称:

com.example.app.flavor1 com.example.app.flavor1.debug com.example.app.flavor2 com.example.app.flavor2.debug com.example.app.flavor1 com.example.app.flavor1.debug com.example.app.flavor2 com.example.app.flavor2.debug

Everything is fine with the code. 代码一切正常。 But because the modified package name get's messed up while merging the manifest I need to set some things like GCM permissions and content providers authority by hand for each valid package. 但是由于合并清单时弄乱了修改后的程序包名称,因此我需要为每个有效程序包手动设置一些内容,例如GCM权限和内容提供者权限。

But how do it do it? 但是如何做到的呢? No matter if I put the AndroidManifest.xml into src/falvor{1,2} or in src/{debug,release} , I end up with only two configurations. 无论我将AndroidManifest.xml放入src/falvor{1,2}还是src/{debug,release} ,最终我只有两种配置。 I tried things like flavor1Debug without luck. 我没有运气就尝试过flavor1Debug东西。

There's no official way to set resource files of the 'flavorBuildType' (like flavor1Debug) combination, so you have to do a little hack here. 没有正式的方法来设置“ flavorBuildType”(如flavour1Debug)组合的资源文件,因此您必须在此处做一些改动。

First define the new path of AndroidManifest.xml: 首先定义AndroidManifest.xml的新路径:

project.ext.flavor1 = [
    debugManifest: 'src/flavor1Debug/AndroidManifest.xml',
    releaseManifest: 'src/flavor1Release/AndroidManifest.xml'
]

project.ext.flavor2 = [
    debugManifest: 'src/flavor2Debug/AndroidManifest.xml',
    releaseManifest: 'src/flavor2Release/AndroidManifest.xml'
]

Second, tell gradle to use the new AndroidManifest.xml in processManifest task. 其次,告诉gradle在processManifest任务中使用新的AndroidManifest.xml。 Now the problem is: sourceSet.manifest.srcFile is read-only, we can't just replace it on-fly. 现在的问题是:sourceSet.manifest.srcFile是只读的,我们不能随便替换它。 Since we're using separate resource (debug & release) for each flavor, we can copy the new AndroidManifest.xml to the origin flavor folder and gradle will build the APK file with right settings. 由于我们为每种口味使用单独的资源(调试和发布),因此我们可以将新的AndroidManifest.xml复制到原始口味文件夹,并且gradle将使用正确的设置构建APK文件。

android.applicationVariants.all { variant ->
    variant.processManifest.doFirst {
        if (project.ext.has(variant.productFlavors.name)) {
            if (project.ext[variant.productFlavors.name].debugManifest != null &&
                project.ext[variant.productFlavors.name].releaseManifest != null) {
                def manifestDirectory = android.sourceSets[variant.productFlavors.name].manifest.srcFile.parentFile
                if (variant.buildType.name.equals("debug")) {
                    copy {
                        from project.ext[variant.productFlavors.name].debugManifest
                        into manifestDirectory
                    }
                } else if (variant.buildType.name.equals("release")) {
                    copy {
                        from project.ext[variant.productFlavors.name].releaseManifest
                        into manifestDirectory
                    }
                }
            }
        }
    }

    variant.processManifest.doLast {
        if (project.ext.has(variant.productFlavors.name)) {
            project.delete android.sourceSets[variant.productFlavors.name].manifest.srcFile
        }
    }
}

And for the AndroidManifest.xml, just leave the GCM related setting there: 对于AndroidManifest.xml,只需在此处保留与GCM相关的设置即可:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android.example.free.debug"
    android:versionCode="1"
    android:versionName="1.0" >

    <permission
        android:name="com.android.example.free.debug.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="com.android.example.free.debug.permission.C2D_MESSAGE" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

</manifest>

You can get sample code here : https://github.com/shakalaca/learning_gradle_android/tree/master/07_tricks 您可以在此处获取示例代码: https : //github.com/shakalaca/learning_gradle_android/tree/master/07_tricks

It supports both Google Maps API v2 & GCM cases, but I think it is easy to support content providers as well after minor code change. 它同时支持Google Maps API v2和GCM案例,但是我认为在更改少量代码后也很容易支持内容提供商。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM