note/程序开发/安卓开发/Gradle.md
2023-08-25 10:49:58 +08:00

11 KiB
Raw Blame History

Groovy 语言

函数调用可以不加括号

配置闭包 android{}

Gradle 配置

gradle 是基于 groovy 语言的项目构建工具

Android Studio 基于 gradle 来构建项目

Project

入口配置文件

  • buildscript

    • 定义 gradle 所需仓库与依赖
  • allprojects{}

    • 定义 Android 项目 所需仓库与依赖
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {//这里是gradle脚本执行所需依赖分别是对应的maven库和插件
    
    repositories {
        google()//从Android Studio3.0后新增了google()配置可以引用google上的开源项目
        jcenter()//是一个类似于github的代码托管仓库声明了jcenter()配置,可以轻松引用 jcenter上的开源项目
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.0'////此处是android的插件gradlegradle是一个强大的项目构建工具
        

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {//这里是项目本身需要的依赖比如项目所需的maven库
    repositories {
        google()
        jcenter()
    }
}

// 运行gradle clean时执行此处定义的task任务。
// 该任务继承自Delete删除根目录中的build目录。
// 相当于执行Delete.delete(rootProject.buildDir)。
// gradle使用groovy语言调用method时可以不用加task clean(type: Delete) {
    delete rootProject.buildDir
}

Module

apply plugin 接口

// 声明是Android程序
//com.android.application 表示这是一个应用程序模块
//com.android.library 标识这是一个库模块
//而这区别:前者可以直接运行,后着是依附别的应用程序运行
apply plugin: 'com.android.application'
apply plugin: 'com.google.firebase.crashlytics'

android 配置

  • signingConfigs
    • 打包配置生成apk文件时的配置
    • release
    • debug
  • compileSdkVersion
    • 设置编译时的Android版本
  • defaultConfig
    • 项目基础信息
  • buildTypes
    • 安装配置安装apk时的配置
    • release
    • debug
  • sourceSets
    • 配置目录指向
    • main
      • jniLibs.srcDirs
  • packagingOption
    • 打包时,包依赖配置
  • productFlavors
    • 多个渠道apk配置

其他配置

  • lintOption
    • 代码扫描分析
  • dependencies
    • 依赖关系
// 声明是Android程序
//com.android.application 表示这是一个应用程序模块
//com.android.library 标识这是一个库模块
//而这区别:前者可以直接运行,后着是依附别的应用程序运行
apply plugin: 'com.android.application'

android {
    signingConfigs {// 自动化打包配置
        release {// 线上环境
            keyAlias 'test'
            keyPassword '123456'
            storeFile file('test.jks')
            storePassword '123456'
        }
        debug {// 开发环境
            keyAlias 'test'
            keyPassword '123456'
            storeFile file('test.jks')
            storePassword '123456'
        }
    }
    compileSdkVersion 27//设置编译时用的Android版本
    defaultConfig {
        applicationId "com.billy.myapplication"//项目的包名
        minSdkVersion 16//项目最低兼容的版本
        targetSdkVersion 27//项目的目标版本
        versionCode 1//版本号
        versionName "1.0"//版本名称
        flavorDimensions "versionCode"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"//表明要使用AndroidJUnitRunner进行单元测试
    }
    buildTypes {// 生产/测试环境配置
        release {// 生产环境
            buildConfigField("boolean", "LOG_DEBUG", "false")//配置Log日志
            buildConfigField("String", "URL_PERFIX", "\"https://release.cn/\"")// 配置URL前缀
            minifyEnabled false//是否对代码进行混淆
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//指定混淆的规则文件
            signingConfig signingConfigs.release//设置签名信息
            pseudoLocalesEnabled false//是否在APK中生成伪语言环境帮助国际化的东西一般使用的不多
            zipAlignEnabled true//是否对APK包执行ZIP对齐优化减小zip体积增加运行效率
            applicationIdSuffix 'test'//在applicationId 中添加了一个后缀,一般使用的不多
            versionNameSuffix 'test'//在applicationId 中添加了一个后缀,一般使用的不多
        }
        debug {// 测试环境
            buildConfigField("boolean", "LOG_DEBUG", "true")//配置Log日志
            buildConfigField("String", "URL_PERFIX", "\"https://test.com/\"")// 配置URL前缀
            minifyEnabled false//是否对代码进行混淆
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//指定混淆的规则文件
            signingConfig signingConfigs.debug//设置签名信息
            debuggable false//是否支持断点调试
            jniDebuggable false//是否可以调试NDK代码
            renderscriptDebuggable false//是否开启渲染脚本就是一些c写的渲染方法
            zipAlignEnabled true//是否对APK包执行ZIP对齐优化减小zip体积增加运行效率
            pseudoLocalesEnabled false//是否在APK中生成伪语言环境帮助国际化的东西一般使用的不多
            applicationIdSuffix 'test'//在applicationId 中添加了一个后缀,一般使用的不多
            versionNameSuffix 'test'//在applicationId 中添加了一个后缀,一般使用的不多
        }
    }

    sourceSets {//目录指向配置
        main {
            jniLibs.srcDirs = ['libs']//指定lib库目录
        }
    }

    packagingOptions{//打包时的相关配置
        //pickFirsts做用是 当有重复文件时 打包会报错 这样配置会使用第一个匹配的文件打包进入apk
        // 表示当apk中有重复的META-INF目录下有重复的LICENSE文件时  只用第一个 这样打包就不会报错
        pickFirsts = ['META-INF/LICENSE']

        //merges何必 当出现重复文件时 合并重复的文件 然后打包入apk
        //这个是有默认值得 merges = [] 这样会把默默认值去掉  所以我们用下面这种方式 在默认值后添加
        merge 'META-INF/LICENSE'

        //这个是在同时使用butterknife、dagger2做的一个处理。同理遇到类似的问题只要根据gradle的提示做类似处理即可。
        exclude 'META-INF/services/javax.annotation.processing.Processor'
    }

    productFlavors {
        wandoujia {}
        xiaomi {}
        _360 {}
    }

    productFlavors.all {
            //批量修改,类似一个循序遍历
        flavor -> flavor.manifestPlaceholders = [IFLYTEK_CHANNEL: name]
    }

    //程序在编译的时候会检查lint有任何错误提示会停止build我们可以关闭这个开关
    lintOptions {
        abortOnError false
        //即使报错也不会停止打包
        checkReleaseBuilds false
        //打包release版本的时候进行检测
    }

}

dependencies {
    
    //声明测试用例库
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}


Build Varient

为一个项目构建多个应用程序

Edit Build Type

  • Debug
  • Release

Edir Flavors

  • 多渠道配置

清单合并

流程与优先级

合并冲突启发式算法

  • <manifest> 元素中的属性绝不合并—仅使用优先级最高的清单中的属性。

  • android:required 属性 >](https://developer.android.com/guide/topics/manifest/uses-feature-element.html?hl=zh-cn) and [ 元素使用 OR 合并,因此如果出现冲突,系统将应用 "true" 并始终包括某个清单所需的功能或库。

  • <uses-sdk>

    元素始终使用优先级较高的清单中的值,但以下情况除外:

    • 如果低优先级清单的 minSdkVersion较高,除非您应用 overrideLibrary 合并规则。
    • 如果低优先级清单的 targetSdkVersion较低,合并工具将使用高优先级清单中的值,但也会添加任何必要的系统权限,以确保所导入的库继续正常工作(适用于较高的 Android 版本具有更多权限限制的情况)。 如需了解有关此行为的详细信息,请参阅有关隐式系统权限的部分。
  • 绝不会在清单之间匹配 <intent-filter> 元素。 每个元素都被视为唯一元素,并添加至合并清单中的常用父元素。

**不依赖于默认属性值。**由于所有唯一属性都合并到相同元素中,如果高优先级清单实际上依赖于属性的默认值而不需要声明,则可能会导致意外结果。例如,如果高优先级清单声明android:launchMode 属性,则会使用 "standard" 的默认值;但如果低优先级清单声明此属性具有其他值,该值将应用于合并清单(替代默认值)。因此,您应该按期望明确定义每个属性。(每个属性的默认值都会记录在 Manifest reference 中)。

合并规则标记

合并规则标记是一个 XML 属性,可用于表达您对关于如何解决合并冲突或删除不需要的元素和属性的首选项。

文章

https://www.jianshu.com/p/e501e2bcf315

『译』Android Studio 合并多个 Manifest


        <provider
            android:name="com.sqwan.msdk.provider.SqFileProvider"
            android:authorities="${applicationId}.provider"
            android:grantUriPermissions="true"
            tools:ignore="MissingClass">
            <meta-data
                android:exported="false"
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_file"/>
        </provider>

        <!-- SQ APPID 参数数字int型数值一般较大 非常重要,请替换为分配给游戏对应的参数 !-->
        <meta-data
            android:name="SQH5SDK.appid"
            android:value="${ZGAME_APP_ID}"/>

        <!-- 聚合 GameID 参数数字int型数值一般较小 非常重要,请替换为分配给游戏对应的参数 !-->
        <meta-data
            android:name="SDK.GAMEID"
            android:value="${ZGAME_GAME_ID}"/>
        <!-- 37GameSDK 的配置结束 -->
        
        
                    signingConfig signingConfigs.interal
            proguardFiles getDefaultProguardFile('proguard-android.txt'), './proguard-rules.pro'
            //applicationId = "com.zapp.c37.demo"
            manifestPlaceholders["ZGAME_CHANNEL"] = "37_hw"
            manifestPlaceholders["ZGAME_GAME_ID"] = "48"
            manifestPlaceholders["ZGAME_APP_ID"] = "599"