Android开发中常用Gradle配置及问题处理(持续更新)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/l460133921/article/details/82769236


该博客是我在使用Android Gradle过程中遇到的问题和学习汇总,博客中的内容主要是参考其他博客。所参考博客的地址都写在参考一节了。

1. Gradle文件结构

对于一个gradle 项目,最基础的文件配置如下:
在这里插入图片描述
一个项目有一个setting.gradle、包括一个顶层的 build.gradle文件、每个Module (如app)都有自己的一个build.gradle文件。

  • setting.gradle:这个 setting 文件定义了哪些module 应该被加入到编译过程,对于单个module 的项目可以不用需要这个文件,但是对于 multimodule 的项目我们就需要这个文件,否则gradle 不知道要加载哪些项目。这个文件的代码在初始化阶段就会被执行。如:
  • ``` include ':app' include ':csc' ```
  • 顶层的build.gradle: 顶层的build.gradle文件的配置最终会被应用到所有项目中。它典型的配置如下
  • buildscript {
        repositories {
            jcenter()
        }
    
        dependencies {
            classpath 'com.android.tools.build:gradle:1.2.3'
        }
    }
    
    allprojects{
        repositories{
            jcenter()
        }
    }
    

    其中:

    1. buildscript:定义了 Android 编译工具的类路径。repositories中,jcenter是一个著Maven 仓库;
    2. allprojects:中定义的属性会被应用到所有 moudle 中,但是为了保证每个项目的独立性,我们一般不会在这里面操作太多共有的东西。
  • 每个项目单独的 build.gradle:针对每个moudle 的配置,如果这里的定义的选项和顶层build.gradle定义的相同,后者会被覆盖。典型的 配置内容如下:每个项目单独的 build.gradle:针对每个moudle 的配置,如果这里的定义的选项和顶层build.gradle定义的相同,后者会被覆盖。典型的 配置内容如下:
  • 在这里插入图片描述
    在这里插入图片描述
    其中:

    1. apply plugin:第一行代码应用了Android 程序的gradle插件,作为Android 的应用程序,这一步是必须的,因为plugin中提供了Android 编译、测试、打包等等的所有task。
    2. android:这是编译文件中最大的代码块,关于android 的所有特殊配置都在这里,这就是我们前面的声明的 plugin 提供的。
    3. defaultConfig:程序的默认配置,注意,如果在AndroidMainfest.xml里面定义了与这里相同的属性,会以这里的为主。
      注意:applicationId的选项:在我们曾经定义的AndroidManifest.xml中,那里定义的包名有两个用途:一个是作为程序的唯一识别ID,防止在同一手机装两个一样的程序;另一个就是作为我们R资源类的包名。在以前我们修改这个ID会导致所有用引用R资源类的地方都要修改。但是现在我们如果修改applicationId只会修改当前程序的ID,而不会去修改源码中资源文件的引用。
    4. buildTypes:定义了编译类型,针对每个类型我们可以有不同的编译配置,不同的编译配置对应的有不同的编译命令。默认的有debug、release 的类型。
    5. dependencies:是属于gradle 的依赖配置。它定义了当前项目需要依赖的其他库。

    2. AAR引用

    协作开发中引用AAR是比较正常的事情,这一条属于基本技能。引用也是十分简单的,直接把aar文件放到libs目录下,然后在gradle下面配置一行:

    repositories{
        flatDir{
            dirs 'libs'
        }
    }
    

    注意:外层的repositories不能少,然后直接就可以在dependencies中添加引用,注意单引号

    compile(name: 'widget2-debug', ext: 'aar')
    

    3. 自动生成versionCode,versionName

    直接依靠gradle的语法来实现版本号的修改,分离主版本子版本,根据自己的逻辑进行修改。

    def versionMajor = 2
    def versionMinor = 1
    def versionPatch = 0
    
    android {
        ...
        defaultConfig {
        ...
            versionCode versionMajor * 100 + versionMinor * 10 + versionPatch
            versionName "${versionMajor}.${versionMinor}.${versionPatch}"
        }
    }
    

    4. 配置release和debug的applicationId

    使用applicationidsuffix可以为debug版本添加一个后缀到你的applicationid上。这个小技巧可以让我们在同一台设备上安装多个版本的apk,不用频繁卸载。

    buildTypes {    
        debug {
            applicationIdSuffix ".debug"
        }
        ...
    }
    

    5. 保持依赖版本同步

    在现在越来越大的项目中,各种Module,子Module,引用版本不一致导致经常需要同步下载,而且一旦想要升级插件,support包之类的,可能有好多个需要同时升级。使用Gradle,我们也能做到这一点。首先在最外层的根build.gradle中,在ext块内定义一个版本

    ext {
        supportLibVer = "24.2.1"
    }
    

    这样我们就能在需要的地方引用了

    dependencies {
        compile fileTree(include: ['*.jar'], dir: 'libs')
        compile "com.android.support:appcompat-v7:$rootProject.ext.supportLibVer"
        compile "com.android.support:design:$rootProject.ext.supportLibVer"
        ...
    }
    

    包版本可以这么玩,其他的所有配置其实都可以这么玩,我们可以把配置抽成一个单独的gradle文件,里面就一个ext block。

    ext {
       androidPluginVer = "2.1.3"
       compileSdkVer = 24
       buildToolsVer = "24.0.2"
    
       minSdkVer = 14
       targetSdkVer = 24
    
       supportLibVer = "24.2.1"
    }
    

    我们把这个命名成config.gradle,然后要做的就是让子module都能引用到这个,简单的做法就是直接让刚才的root gradle文件引用这个gradle配置文件。
    这里有一点坑就是看你自己创建的gradle目录在哪一级,需要定位到才能找得到 不然会出错,这里我是在最外层,所以加了两处,另外改ext属性,需要手动同步一下,直接跑的话并不会自动同步,这是最关键的一点。

    buildscript {
        apply from: 'config.gradle'
        ...
    }
    
    subprojects {
        apply from: '../config.gradle'
    }
    

    使用的话和前面的ext属性差不多,加不加rootProject都可以跑得动

    6. 编译成library

    如果我们要将一个module编译成library让其他的项目引用,我们需要在该module的bubild.gradle中将plugin设置为如下plugin:

    apply plugin: 'com.android.library'
    

    7. 优化编译速度

    可以通过以下方式加快gradle 的编译:

  • 开启并行编译
  • 在项目根目录下面的 gradle.properties中设置
    org.gradle.parallel=true
    
  • 开启编译守护进程
  • 该进程在第一次启动后回一直存在,当你进行二次编译的时候,可以重用该进程。同样是在gradle.properties中设置
    org.gradle.daemon=true
    
  • 加大可用编译内存
  • 同样是在gradle.properties中设置
    org.gradle.jvmargs=-Xms256m -Xmx1024m
    

    引用的时候在setting文件中include即可。

    8. 自动优化无用的资源

    在编译的时候,我们可能会有很多资源并没有用到,此时就可以通过shrinkResources来优化我们的资源文件,除去那些不必要的资源。
    在这里插入图片描述
    某些情况下,一些资源是需要通过动态加载的方式载入的,这时候我也需要像 Progard 一样对我们的资源进行keep操作。方法就是在res/raw/下建立一个keep.xml文件,通过如下方式 keep 资源:
    在这里插入图片描述

    9. Gradle依赖配置compile,implementation和api的区别

    Gradle3.4之前的版本使用如下方式添加依赖:

    dependencies {
    compile 'commons-httpclient:commons-httpclient:3.1'
    compile 'org.apache.commons:commons-lang3:3.5'
    }
    

    Gradle 3.4+后使用如下方式添加依赖:

    dependencies {
    api 'commons-httpclient:commons-httpclient:3.1'
    implementation 'org.apache.commons:commons-lang3:3.5'
    }
    

    其中api和implementation两种依赖的不同点在于:它们声明的依赖其他模块是否能使用。

    • api:当其他模块依赖于此模块时,此模块使用api声明的依赖包是可以被其他模块使用
    • implementation:当其他模块依赖此模块时,此模块使用implementation声明的依赖包只限于模块内部使用,不允许其他模块使用。

    10. FAQ

    10.1 Gradle sync failed: ‘xxx’ already disposed:

    错误特征:

    14:37   Gradle sync started
    14:37   Gradle sync failed: 'shadows-core-3.0' already disposed:
    14:37   Gradle sync completed
    14:39   Gradle sync started
    14:39   Gradle sync failed: 'robolectric-resources-3.0' already disposed:
    14:40   Gradle sync completed
    

    解决方法:
    ./gradlew clean
    Restart Android stduio

    10.2 调试时出现“line number info is not available”

    编译debug版本时打开了混淆开关,按如下方式修改:

    buildTypes {
            debug {
                testCoverageEnabled = true
                debuggable true
                minifyEnabled false //值改为false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
                signingConfig signingConfigs.debug
            }
            ......
     }
    

    参考

    1. Android开发中那些常用的Gradle配置. https://www.jianshu.com/p/d412e04ab38d
    2. Android Gradle 完整指南. https://www.cnblogs.com/laughingQing/p/5855774.html
    3. https://www.jianshu.com/p/1eac2ecacf88

    猜你喜欢

    转载自blog.csdn.net/l460133921/article/details/82769236