Android Studio 和Gradle Plugin 3.

2017-11-03  本文已影响389人  宇行信

Android Studio 3.0 默认Gradle版本为4.1,如果你需要手动升级版本的话,记得修改gradle/wrapper/gradle-wrapper.properties文件的URL地址:

distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip

对应的Gradle插件版本为3.0.0,手动修改的话,需要修改项目级的build.gradle文件:

buildscript {
    repositories {
        ...
        // You need to add the following repository to download the
        // new plugin.
        google()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.0'
    }
}

注意上面记得添加google这个repository,某些官方依赖需要下载

对应我们的构建工具buildToolsVersion版本为26.0.2,对应Module级项目build.gradle文件:

android {
    compileSdkVersion 26
    ...
    defaultConfig {
      ...
    }
}
  1. 添加风味维度的声明
    当我们在配置文件中配置产品风味的时候,现在需要声明风味维度,然后在每个产品风味中指定你前面所声明的某一个风味维度,如下:

    //定义两个风味维度
    flavorDimensions "api", "mode"
    
    productFlavors {
         demo {
             //指定风味维度
            dimension "mode"
            ...
         }
         
         full {
            dimension "mode"
            ...
         }
         
         minApi24 {
             dimension "api"
             minSDKVersion '24'
             versionNameSuffix "-minApi24"
         }
         
         minApi23 {
             dimension "api"
             minSDKVersion '23'
             versionNameSuffix "-minApi23"
         }
         
         minApi21 {
             dimension "api"
             minSDKVersion '21'
             versionNameSuffix "-minApi21"
         }
    }
    

    如上,配置完后,Gradle创建的构建变体数量等于每个风味维度中的风味数量与你配置的构建类型数量的乘积,在 Gradle 为每个构建变体或对应 APK 命名时,属于较高优先级风味维度的产品风味首先显示,之后是较低优先级维度的产品风味,再之后是构建类型。以上面的构建配置为例,Gradle 可以使用以下命名方案创建总共 12 个构建变体:
    构建变体:[minApi24, minApi23, minApi21][Demo, Full][Debug, Release]
    对应 APK:app-[minApi24, minApi23, minApi21]-[demo, full]-[debug, release].apk
    例如构建变体:minApi24DemoDebug,对应 APK:app-minApi24-demo-debug.apk
    当然如果有些特定的变体不是你需要的,你也可以过滤:

    android{
        variantFilter { variant ->
            def names = variant.flavors*.name
            // To check for a certain build type, use variant.buildType.name == "<buildType>"
            if (names.contains("minApi21") && names.contains("demo")) {
            // Gradle ignores any variants that satisfy the conditions above.
            setIgnore(true)
            }
        }
    }
    

    如果组合多个产品风味,产品风味之间的优先级将由它们所属的风味维度决定。上面所列示的第一个风味维度中的产品风味比第二个维度中的产品风味拥有更高的优先级,以此类推。此外,与属于各个产品风味的源集相比,你为产品风味组合创建的源集拥有更高的优先级。

    如果不同源集包含同一文件的不同版本,Gradle 将按以下优先顺序决定使用哪一个文件(左侧源集替换右侧源集的文件和设置):

    构建变体 > 构建类型 > 产品风味 > 主源集 > 库依赖项

    如以下优先级顺序:

    1. src/demoDebug/(构建变体源集)
    2. src/debug/(构建类型源集)
    3. src/demo/(产品风味源集)
    4. src/main/(主源集)
      这里说下源集的概念,Android Studio 按逻辑关系将每个模块的源代码和资源分组称为源集,默认情况下,Android Studio 会创建 main/源集和目录,用于存储要在所有构建变体之间共享的一切资源。然而,我们也可以创建新的源集来控制 Gradle 要为特定的构建类型、产品风味(以及使用风味维度时的产品风味组合)和构建变体编译和打包的确切文件。例如,可以在 main/ 源集中定义基本的功能,使用产品风味源集针对不同的客户更改应用的品牌,或者仅针对使用调试构建类型的构建变体包含特殊的权限和日志记录功能等。
      • src/main/:此源集包括所有构建变体共用的代码和资源。
      • src/<buildType>/:创建此源集可加入特定构建类型专用的代码和资源。
      • src/<productFlavor>/:创建此源集可加入特定产品风味专用的代码和资源。
      • src/<productFlavorBuildType>/:创建此源集可加入特定构建变体专用的代码和资源。

    配置完后我们可以通过Android Studio窗口右侧Gradle,导航至YourApplication>Tasks>android下双击sourceSets,在Android Studio底部右下角 Gradle Console处查看项目是如何组织源集的

  1. 关于构建类型的配置,假设App中配置了一个叫做"jniDebug"的构建类型,但是该App所依赖的库中没有配置,这时候当我们构建"jniDebug"的时候,插件就不知道库该使用什么构建类型,这时候就会给报出下面的错误:

    Error:Failed to resolve: Could not resolve project :mylibrary.
    Required by:project :app
    

    这类问题就是由于上面的依赖管理机制变化导致的,我们可以下面的几种情况来分别解决:

    • 你的 Module App 包含了它所依赖的库没有的构建类型

      例如,我们的App包含了一个jniDebug的构建类型,但是它所依赖的库中没有这个,而是有debug和release这两个构建类型,这时候我们就可以在Module App的build.gradle文件中使用matchingFallbacks 来指定可以替换的匹配项,如下:

      android {
          buildTypes {
              debug {}
              release {}
              jniDebug {
                  // Specifies a sorted list of fallback build types that the
                  // plugin should try to use when a dependency does not include a
                  // "jniDebug" build type. You may specify as many fallbacks as you
                  // like, and the plugin selects the first build type that's
                  // available in the dependency.
                  matchingFallbacks = ['debug', 'release']
              }
          }
      }
      

      值得一提的是插件会选择matchingFallbacks列表中第一个可用的构建类型来替换匹配项。

      注意当依赖的库中包含了Module App没有的构建类型,则不会出现上述问题。

    • 对于一个给定的存在于App和它所依赖的库中的风味维度,我们的主Module App包含了库中没有的风味:

      例如,主Module App和库中都包含了一个mode的风味维度,我们的App中指定mode维度的是free和paid风味,而库中指定mode维度的是demo和paid风味,这时候我们就可以用`matchingFallbacks 来为App中的free指定可以替换的匹配项。如下:

      android {
                defaultConfig{
                // Do not configure matchingFallbacks in the defaultConfig block.
                // Instead, you must specify fallbacks for a given product flavor in the
                // productFlavors block, as shown below.
              }
                flavorDimensions 'mode'
                productFlavors {
                    paid {
                        dimension 'mode'
                        // Because the dependency already includes a "paid" flavor in its
                        // "mode" dimension, you don't need to provide a list of fallbacks
                        // for the "paid" flavor.
                    }
                    free {
                        dimension 'mode'
                        // Specifies a sorted list of fallback flavors that the plugin
                        // should try to use when a dependency's matching dimension does
                        // not include a "free" flavor. You may specify as many
                        // fallbacks as you like, and the plugin selects the first flavor
                        // that's available in the dependency's "mode" dimension.
                        matchingFallbacks = ['demo', 'trial']
                    }
                }
            }
      

      值得注意的是,上述情况中,如果说库中包含了一个主Module App没有的产品风味,则不会出现上述问题。

    • 库中包含了一个主Module App没有的风味维度

      例如,库中声明了一个minApi的风味维度,但是你的App中只有mode维度,因此当你要构建freeDebug这个变种版本的App时,插件就不知道你是想用minApi23Debug还是用minApi25Debug变种版本的库,这时候我们可以在主Module App中的defaultConfig代码块通过配置missingDimensionStrategy来让插件从丢失的维度中指定默认的风味,当然你也可以在productFlavors代码块中覆盖先前的选择,因此每一个风味都可以为丢失的维度指定一个不同的匹配策略。

      android {
         defaultConfig{
                // Specifies a sorted list of flavors that the plugin should try to use from
                // a given dimension. The following tells the plugin that, when encountering
                // a dependency that includes a "minApi" dimension, it should select the
                // "minApi23" flavor. You can include additional flavor names to provide a
                // sorted list of fallbacks for the dimension.
                missingDimensionStrategy 'minApi', 'minApi23', 'minApi25'
                // You should specify a missingDimensionStrategy property for each
                // dimension that exists in a local dependency but not in your app.
                missingDimensionStrategy 'abi', 'x86', 'arm64'
          }
          flavorDimensions 'mode'
          productFlavors {
              free {
                  dimension 'mode'
                  // You can override the default selection at the product flavor
                  // level by configuring another missingDimensionStrategy property
                  // for the "minApi" dimension.
                  missingDimensionStrategy 'minApi', 'minApi25', 'minApi23'
              }
              paid {}
          }          
      }
      

      值得注意的是,当你的主Module App中包含了一个库中依赖项没有的风味维度时,则不会出现上述问题。例如,当库中依赖项不包含abi这个维度时,freeX86Debug版本将会使用freeDebug版本的依赖。

参考

  1. https://developer.android.com/studio/write/java8-support.html#migrate
  2. https://android-developers.googleblog.com/2017/10/android-studio-30.html
  3. https://developer.android.com/studio/build/gradle-plugin-3-0-0.html#known_issues
  4. https://developer.android.com/studio/build/gradle-plugin-3-0-0-migration.html
上一篇 下一篇

猜你喜欢

热点阅读