基于Android Gradle中多风格库的多风格应用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24860659/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 08:51:54  来源:igfitidea点击:

Multi flavor app based on multi flavor library in Android Gradle

androidgradleandroid-gradle-plugin

提问by Ali

My app has several flavors for several markets in-app-billing systems.

我的应用程序为多个市场应用程序内计费系统提供了多种风格。

I have a single library which shares the base code for all of my projects. So I decided to add those payment systems to this library as product flavors.

我有一个库,它共享我所有项目的基本代码。所以我决定将这些支付系统作为产品风格添加到这个库中。

The question is can android library have product flavors?

问题是android库可以有产品口味吗?

If so, how can I include different flavors in respective flavor of the app?

如果是这样,我如何在应用程序的各个风格中包含不同的风格?

I searched a lot, and I couldn't find anything about this scenario. The only close thing I found was this in http://tools.android.com/tech-docs/new-build-system/user-guide:

我搜索了很多,我找不到关于这个场景的任何信息。我发现的唯一接近的东西是http://tools.android.com/tech-docs/new-build-system/user-guide

dependencies {
    flavor1Compile project(path: ':lib1', configuration: 'flavor1Release')
    flavor2Compile project(path: ':lib1', configuration: 'flavor2Release')
}

I changed configuration to different things but it did not work!

我将配置更改为不同的东西,但没有用!

I'm using android studio 0.8.2.

我正在使用 android studio 0.8.2。

回答by Ali

Finally I found out how to do this, I will explain it here for others facing same problem:

最后我找到了如何做到这一点,我将在这里为面临同样问题的其他人解释:

The key part is to set publishNonDefault to true in library build.gradle, Then you must define dependencies as suggested by user guide.

关键部分是在库 build.gradle 中将 publishNonDefault 设置为 true,然后您必须按照用户指南的建议定义依赖项。

The whole project would be like this:

整个项目应该是这样的:

Library build.gradle:

库 build.gradle:

apply plugin: 'com.android.library'

android {        
    ....
    publishNonDefault true
    productFlavors {
        market1 {}
        market2 {}
    }
}

project build.gradle:

项目 build.gradle:

apply plugin: 'com.android.application'

android {
    ....
    productFlavors {
        market1 {}
        market2 {}
    }
}

dependencies {
    ....
    market1Compile project(path: ':lib', configuration: 'market1Release')
    market2Compile project(path: ':lib', configuration: 'market2Release')
}

Now you can select the app flavor and Build Variants panel and the library will be selected accordingly and all build and run will be done based on the selected flavor.

现在您可以选择应用程序风格和构建变体面板,将相应地选择库,所有构建和运行都将根据所选风格完成。

If you have multiple app module based on the library Android Studio will complain about Variant selection conflict, It's ok, just ignore it.

如果你有多个基于库的应用模块,Android Studio 会抱怨 Variant selection 冲突,没关系,忽略它。

enter image description here

在此处输入图片说明

回答by AppiDevo

There are one problem with Alianswer. We are losing one very important dimension in our build variants. If we want to have all options (in my example below 4 (2 x 2)) we just have to add custom configurationsin main module build.gradlefile to be able to use all multi-flavor multi-buildType in Build Variants. We also have to set publishNonDefault truein the library module build.gradlefile.

阿里回答有一个问题。在我们的构建变体中,我们正在失去一个非常重要的维度。如果我们想拥有所有选项(在我下面的示例中为 4 (2 x 2)),我们只需要在主模块 build.gradle文件中添加自定义配置,以便能够在. 我们还必须在库模块 build.gradle文件中设置publishNonDefault trueBuild Variants

Example solution:

示例解决方案:

Lib build.gradle

Lib build.gradle

android {

    publishNonDefault true

    buildTypes {
        release {
        }
        debug {
        }
    }
    productFlavors {
        free {
        }
        paid {
        }
    }
}

App build.gradle

应用程序构建.gradle

android {

    buildTypes {
        debug {
        }
        release {
        }
    }
    productFlavors {
        free {
        }
        paid {
        }
    }
}

configurations {
    freeDebugCompile
    paidDebugCompile
    freeReleaseCompile
    paidReleaseCompile
}

dependencies {

    freeDebugCompile project(path: ':lib', configuration: 'freeDebug')
    paidDebugCompile project(path: ':lib', configuration: 'paidDebug')
    freeReleaseCompile project(path: ':lib', configuration: 'freeRelease')
    paidReleaseCompile project(path: ':lib', configuration: 'paidRelease')

}

回答by Harsh4789

Update for Android Plugin 3.0.0 and higher

Android 插件 3.0.0 及更高版本的更新

According to the official Android Documentation - Migrate dependency configurations for local modules,

根据官方 Android 文档 -为本地模块迁移依赖项配置

With variant-aware dependency resolution, you no longer need to use variant-specific configurations, such as freeDebugImplementation, for local module dependencies—the plugin takes care of this for you

You should instead configure your dependencies as follows:

通过变体感知依赖项解析,您不再需要对本地模块依赖项使用变体特定的配置,例如 freeDebugImplementation——插件会为您处理这些

您应该按如下方式配置您的依赖项:

dependencies {
    // This is the old method and no longer works for local
    // library modules:
    // debugImplementation project(path: ':library', configuration: 'debug')
    // releaseImplementation project(path: ':library', configuration: 'release')

    // Instead, simply use the following to take advantage of
    // variant-aware dependency resolution. You can learn more about
    // the 'implementation' configuration in the section about
    // new dependency configurations.
    implementation project(':library')

    // You can, however, keep using variant-specific configurations when
    // targeting external dependencies. The following line adds 'app-magic'
    // as a dependency to only the "debug" version of your module.

    debugImplementation 'com.example.android:app-magic:12.3'
}

So in Ali's answer, change

所以在阿里的回答中,改变

dependencies {
    ....
    market1Compile project(path: ':lib', configuration: 'market1Release')
    market2Compile project(path: ':lib', configuration: 'market2Release')
}

to

implementation project(':lib')

And plugin will take care of variant specific configurations automatically. Hope it helps to others upgrading Android Studio Plugin to 3.0.0 and higher.

插件将自动处理特定于变体的配置。希望它有助于其他人将 Android Studio 插件升级到 3.0.0 及更高版本。

回答by JiajiaGu

My Android Plugin is 3.4.0,and I find that it doesn't need configurations now.All you need is to make sure the flavorDimensions and productFlavors in application contains one productFlavor of the same flavorDimensions and productFlavors in libraries.For sample:

我的Android插件是3.4.0,我发现它现在不需要配置。你需要的是确保应用程序中的flavorDimensions和productFlavors在库中包含一个相同flavorDimensions和productFlavors的productFlavor。例如:

In mylibrary's build.gradle

在 mylibrary 的 build.gradle 中

apply plugin: 'com.android.library'

android {        
    ....
    flavorDimensions "mylibFlavor"

    productFlavors {
        market1
        market2
    }
}

application's build.gradle:

应用程序的 build.gradle:

apply plugin: 'com.android.application'

android {
    ....
    flavorDimensions "mylibFlavor", "appFlavor"
    productFlavors {
        market1 {
            dimension "mylibFlavor"
        }
        market2 {
            dimension "mylibFlavor"
        }
        common1 {
            dimension "appFlavor"
        }
        common2 {
            dimension "appFlavor"
        }
    }
}

dependencies {
    ....
    implementation project(path: ':mylibrary')
}

After sync,you can switch all options in Build Variants Window: enter image description here

同步后,您可以在 Build Variants 窗口中切换所有选项: 在此处输入图片说明

回答by David Lev

To get the flavors working on an AAR library, you need to define defaultPublishConfig in the build.gradle file of your Android Library module.

为了让风格在 AAR 库上工作,您需要在 Android 库模块的 build.gradle 文件中定义 defaultPublishConfig。

For more information, see: Library Publication.

有关更多信息,请参阅:图书馆出版物

Library Publication

By default a library only publishes its release variant. This variant will be used by all projects referencing the library, no matter which variant they build themselves. This is a temporary limitation due to Gradle limitations that we are working towards removing. You can control which variant gets published:

android { defaultPublishConfig "debug" }

Note that this publishing configuration name references the full variant name. Release and debug are only applicable when there are no flavors. If you wanted to change the default published variant while using flavors, you would write:

android { defaultPublishConfig "flavor1Debug" }

图书馆刊物

默认情况下,库仅发布其发布版本。引用该库的所有项目都将使用此变体,无论它们自己构建哪个变体。由于我们正在努力消除 Gradle 限制,这是一个临时限制。您可以控制发布哪个变体:

android { defaultPublishConfig“调试”}

请注意,此发布配置名称引用了完整的变体名称。发布和调试仅适用于没有口味的情况。如果您想在使用风味时更改默认发布的变体,您可以编写:

android { defaultPublishConfig "flavor1Debug" }

回答by AlexG

I know this subject has been closed, but just an update with gradle 3.0, see this : https://developer.android.com/studio/build/gradle-plugin-3-0-0-migration.html#variant_awareand grep matchingFallbacksand missingDimensionStrategy. Now it's way more simple to declare the dependencies between module flavors.

我知道这个主题已经关闭,但只是 gradle 3.0 的更新,请参阅:https: //developer.android.com/studio/build/gradle-plugin-3-0-0-migration.html#variant_aware和 grepmatchingFallbacksmissingDimensionStrategy。现在,声明模块风格之间的依赖关系更加简单。

...and in this precise case with gradle3.0, as flavors share the same name, gradle would map them magically, there is no configuration required.

...在 gradle3.0 的这种精确情况下,由于口味共享相同的名称,gradle 会神奇地映射它们,不需要配置。

回答by Sergio

I also ran into a problem compiling modules for various options.

我还遇到了为各种选项编译模块的问题。

What i've found:

我发现了什么:

It looks like we don't need add publishNonDefault trueinto lib's build.gradlefile, since Gradle 3.0.1.

看起来我们不需要添加publishNonDefault true到 lib 的build.gradle文件中,因为Gradle 3.0.1

After decompiling a class BaseExtensionfound this:

反编译一个类后BaseExtension发现:

public void setPublishNonDefault(boolean publishNonDefault) {
   this.logger.warn("publishNonDefault is deprecated and has no effect anymore. All variants are now published.");
}

And instead of:

而不是:

dependencies {
...
   Compile project(path: ':lib', configuration: 'config1Debug')
}

We should use:

我们应该使用:

dependencies {
...
   implementation project(':lib')
}

Only the important thing, is to add a configurations {...}part to the build.gradle.

只有最重要的事情,是一个增加configurations {...}部分的build.gradle

So, the final variant of app's build.gradlefile is:

因此,应用程序build.gradle文件的最终变体是:

buildTypes {
   debug {
      ...
   }

   release {
      ...
   }
}

flavorDimensions "productType", "serverType"
productFlavors {
   Free {
      dimension "productType"
      ...
   }
   Paid {
      dimension "productType"
      ...
   }
   Test {
      dimension "serverType"
      ...
   }
   Prod {
      dimension "serverType"
      ...
   }
}

configurations {
   FreeTestDebug
   FreeTestRelease
   FreeProdDebug
   FreeProdRelease
   PaidTestDebug
   PaidTestRelease
   PaidProdDebug
   PaidProdRelease
}

dependencies {
   implementation fileTree(dir: 'libs', include: ['*.jar'])
   implementation project(':lib')
   ...
}

Also, you can use Filter variantsto restrict build variants.

此外,您可以使用过滤器变体来限制构建变体。

P.s. don't forget to include modules in the settings.gradlefile, like:

Ps 不要忘记在settings.gradle文件中包含模块,例如:

include ':app'
include ':lib'
project(':lib').projectDir = new File('app/libs/lib')

回答by Delblanco

At the moment it's not possible, although if I recall correctly its a feature they want to add. (Edit 2: link, link2)

目前这是不可能的,但如果我没记错的话,他们想添加一个功能。(编辑2:链接LINK2

Edit: For the moment I'm using the defaultPublishConfigoption to declare which library variant get's published:

编辑:目前我正在使用该defaultPublishConfig选项来声明发布了哪个库变体:

android {
    defaultPublishConfig fullRelease
    defaultPublishConfig demoRelease 
}