zoukankan      html  css  js  c++  java
  • Android gradle Plugin

    参考

    https://developer.android.com/studio/build

    http://google.github.io/android-gradle-dsl/current/index.html

    https://developer.android.com/reference/tools/gradle-api/classes

    说明

    学习gradle最烦人的就是api不知道去哪查询,想要实现某个打包功能只能去网上copy人家的,

    gradle官方的文档还好,但Android gradle plugin的官方文档却更新不及时,原来的文档一直是3.4的,

    现在竟然完全删除了,真tm狗东西,现在只有api了,想要深入只能通过complieOnly导入gradle依赖,下边有说明。

    android gradle plugin版本查询

    https://developer.android.com/studio/releases/gradle-plugin

    gradle plugin和gradle版本对应

    Plugin version

    Required Gradle version

    1.0.0 - 1.1.3

    2.2.1 - 2.3

    1.2.0 - 1.3.1

    2.2.1 - 2.9

    1.5.0

    2.2.1 - 2.13

    2.0.0 - 2.1.2

    2.10 - 2.13

    2.1.3 - 2.2.3

    2.14.1+

    2.3.0+

    3.3+

    3.0.0+

    4.1+

    3.1.0+

    4.4+

    3.2.0 - 3.2.1

    4.6+

    3.3.0 - 3.3.3

    4.10.1+

    3.4.0 - 3.4.3

    5.1.1+

    3.5.0 - 3.5.4

    5.4.1+

    3.6.0 - 3.6.4

    5.6.4+

    4.0.0+

    6.1.1+

    4.1.0+

    6.5+

    Extension types

    Listed below are the Gradle extension types used by respective plugins:

    Type

    Description

    AppExtension

    The android extension for application plugins.

    LibraryExtension

    The android extension for com.android.library projects.

    TestExtension

    android extension for com.android.test projects.

    FeatureExtension

    The android extension for com.android.feature projects.

    Configuration blocks

    下边列出了在android{}的closure中可访问的配置

    Block

    Description

    aaptOptions { }

    Specifies options for the Android Asset Packaging Tool (AAPT).

    adbOptions { }

    Specifies options for the Android Debug Bridge (ADB), such as APK installation options.

    buildTypes { }

    Encapsulates all build type configurations for this project.

    compileOptions { }

    Specifies Java compiler options, such as the language level of the Java source code and generated bytecode.

    dataBinding { }

    Specifies options for the Data Binding Library.

    defaultConfig { }

    Specifies defaults for variant properties that the Android plugin applies to all build variants.

    dexOptions { }

    Specifies options for the DEX tool, such as enabling library pre-dexing.

    externalNativeBuild { }

    Configures external native build using CMake or ndk-build.

    jacoco { }

    Configure JaCoCo version that is used for offline instrumentation and coverage report.

    lintOptions { }

    Specifies options for the lint tool.

    packagingOptions { }

    Specifies options and rules that determine which files the Android plugin packages into your APK.

    productFlavors { }

    Encapsulates all product flavors configurations for this project.

    signingConfigs { }

    Encapsulates signing configurations that you can apply to BuildType and ProductFlavor configurations.

    sourceSets { }

    Encapsulates source set configurations for all variants.

    splits { }

    Specifies configurations for building multiple APKs or APK splits.

    testOptions { }

    Specifies options for how the Android plugin should run local and instrumented tests.

    AppExtension

    其实对应的就是app中的build.gradle中的android,它对应的类型是BaseAppModuleExtension,继承关系如下:

    • BaseAppModuleExtension实现了AppExtensionApplicationExtension
    • ApplicationExtension实现了 CommonExtensionApkExtensionTestedExtension

    BaseAppModuleExtension是内部的api,在api文档中被隐藏了,其实大部分的属性方法都是在CommonExtension中定义的。

    variantFilter

    https://developer.android.com/studio/build/build-variants.html#filter-variants

    variantFilter(Action<VariantFilter> filter)

    在这里你可以对variant进行过滤,通过调用VariantFilter.setIgnore(true)。

    android {
        ...
        variantFilter { variant ->
    
            def buildTypeName = variant.buildType*.name
            def flavorName = variant.flavors*.name
    
            if (flavorName.contains("dev") && buildTypeName.contains("release")) {
                // Tells Gradle to ignore each variant that satisfies the conditions above.
                setIgnore(true)
            }
        }
    }

    applicationVariants

    DomainObjectSet<ApplicationVariant> applicationVariants

    ApplicationVariant在com.android.build.gradle.api.ApplicationVariant

    你可以在这里获取到最终的可构建的variant,你可以在此处对各variant进行属性修改。

    另外由于此集合时DomainObjectSet,所以应该使用.all来遍历,而不是each,原因是插件只在project is evaluated之后才填充此集合。

    android.applicationVariants.all { variant ->
        StringBuilder sb = new StringBuilder()
        for (def productFlavor : variant.productFlavors) {
            sb.append(productFlavor.name)
        }
        println "productFlavor:$sb, buildType:$variant.buildType.name, applicationId:$variant.applicationId"
    
        def mergedFlavor = variant.getMergedFlavor()
        if ("debug".equalsIgnoreCase(variant.buildType.name)) {
            mergedFlavor.applicationId = "com.fuck.you"
            mergedFlavor.manifestPlaceholders = [hostName:"www.example.com/${variant.versionName}"]
        }
    }

    通过variant.getMergedFlavor()获取最后组合的flavor,通过这个productFlavor可以修改最后的包名、placeholder等等属性。

    自定义打包后要输出的目录

    def releaseTime() {
        return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
    }
    
    android{
        applicationVariants.all { variant ->
            variant.outputs.each { output ->
                def outputFile = output.outputFile
                if (outputFile != null && outputFile.name.endsWith('.apk')) {
                    File outputDirectory = new File(outputFile.parent);
                    def fileName
                    if (variant.buildType.name == "release") {
                        fileName =  "app_v${defaultConfig.versionName}_${releaseTime()}_${variant.productFlavors[0].name}.apk"
                    } else {
                        fileName = "app_v${defaultConfig.versionName}_${packageTime()}_debug.apk"
                    }
                    output.outputFile = new File(outputDirectory, fileName)
                }
            }
        }
    }

    在Android Gradle Plugin 4.x中Variant新的配置方式

    https://medium.com/androiddevelopers/new-apis-in-the-android-gradle-plugin-f5325742e614

    以下是Android项目构建所经历的阶段的概述:

    1. 运行Build scripts,允许构建和插件配置Android Gradle Plugin DSL对象以及注册variant 回调。

    2. Android Gradle Plugin 结合了build types和product flavors来创建variants 和test components。

    3. 将为每个variant调用onVariants,从而允许自定义variant设置,并为每个测试组件均调用onTestComponent。

    4. 将为每个启用的variant调用onVariantProperties,并为每个启用的测试组件调用onTestComponentProperties,从而允许注册使用或修改构建中间件的任务。

    5. 在调用onVariants和onVariantProperties回调后,Android Gradle Plugin 插件会为variant注册task。

    6. 使用已注册task,为每个variant调用先前的variant API。

    7. Gradle计算task graph,构建即可开始执行。

    import com.android.build.api.variant.impl.ApplicationVariantPropertiesImpl
    import com.android.build.api.variant.impl.ApplicationVariantImpl
    import com.android.build.gradle.internal.dsl.BaseAppModuleExtension
    
    apply plugin: 'com.android.application'
    
    android { BaseAppModuleExtension appModuleExtension ->
        onVariants { ApplicationVariantImpl applicationVariant ->
    
            StringBuilder sb = new StringBuilder()
            sb.append("name:" + applicationVariant.name + ", ")
            sb.append("flavorName:" + applicationVariant.flavorName + ", ")
            sb.append("productFlavors:" + applicationVariant.productFlavors + ", ")
            sb.append("buildType:" + applicationVariant.buildType + ", ")
            println sb
        }
    
        onVariantProperties { ApplicationVariantPropertiesImpl applicationVariantProperties ->
            StringBuilder sb = new StringBuilder()
            sb.append("productFlavor:$applicationVariantProperties.name, ")
            sb.append("buildType:$applicationVariantProperties.buildType, ")
            sb.append("applicationId:" + applicationVariantProperties.applicationId.get() + ", ")
            println sb
    
    
            // API 'MergedFlavor.getApplicationId()' is obsolete and has been replaced with 'VariantProperties.getApplicationId()'.
            // It will be removed in version 5.0 of the Android Gradle plugin.
            if ("debug".equalsIgnoreCase(applicationVariantProperties.buildType)) {
                applicationVariantProperties.applicationId.set(mlwDebugApplicationId)
            }
    
            //修改打包的名字
            applicationVariantProperties.outputs.each { output ->
                def date = new Date().format('yyyy_MMdd_HHmm')
                def file = output.outputFileName.get()
                def fileName = file.replace(".apk", "_" + android.defaultConfig.versionName + "_" + date + ".apk").replaceFirst("app", "rent_customer").replace("-", "_")
                output.outputFileName.set(fileName)
                //        println "output.outputFileName:" + output.outputFileName
            }
        }
    }

    上边的导入的api需要添加依赖才不会变红

    compileOnly group: 'com.android.tools.build', name: 'gradle', version: '4.1.0'

    在 Android Gradle Plugin 5.0中R.xxx不再是final

    https://sites.google.com/a/android.com/tools/tips/non-constant-fields

    Resource IDs will be non-final in Android Gradle Plugin version 5.0, avoid using them in switch case statements

    一般我们会在onClick中使用switch(id)来检索对应操作,

    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.iv_close: {
                dismiss();
                break;
            }
            case R.id.bt_share: {
                if (onClickListener != null) {
                    onClickListener.onClick(v);
                }
                dismiss();
                break;
            }
        }
    }

    但在Android Gradle Plugin version 5.0中,资源id都不是final了,而switch在编译器就把R.id.xx的值写入到class中,不是final就意味着可能发生改变,那么在运行时的时候可能就找不到对应的case了,

    解决方法就是:

    把switch换成if else,在as中选中switch关键字,然后键盘输入show context action的快捷键(我的是alt+enter),就会弹出快捷转换操作。

    wps3

  • 相关阅读:
    将已排序的数组乱序
    Roadmap!!
    测试
    最大对称字串
    约瑟夫环问题
    大家好
    MYSQL数据库导入SQL文件出现乱码如何解决
    Hibernate缓存
    Spring备忘四(涵盖Spring2.5)
    Struts2 Hello,Wold
  • 原文地址:https://www.cnblogs.com/muouren/p/13949121.html
Copyright © 2011-2022 走看看