Android studio gradle简单解析及使用指南

gradle简单解析

gradle概述

Gradle 是 Android 现在主流的编译工具,对于一些简单的程序我们几乎不需要任何代码上的配置只使用 Android Studio 就可以完成编译和运行。
通过了解gradle,我们可以做:

  • 自定义编译输出文件格式
  • hook Android 编译过程
  • 配置和改善 Gradle 编译速度
  • 等等…

gradle编译周期

在解析 Gradle 的编译过程之前我们需要理解在 Gradle 中非常重要的两个对象。ModuleTask

每个项目的编译至少有一个 Module,一个 build.gradle就代表一个Module,每个Module里面包含了多个task,task 里面又包含很多actionaction是一个代码块,里面包含了需要被执行的代码。

在编译过程中, Gradle 会根据 build 相关文件,聚合所有的Moduletask,执行task 中的 action。因为 build.gradle文件中的task非常多,先执行哪个后执行那个需要一种逻辑来保证。这种逻辑就是依赖逻辑,几乎所有的Task 都需要依赖其他 task 来执行,没有被依赖的task 会首先被执行。所以到最后所有的 Task 会构成一个 有向无环图(DAG Directed Acyclic Graph)的数据结构。

编译过程分为三个阶段:

  • 初始化阶段:创建 Project 对象,如果有多个build.gradle,也会创建多个project。
  • 配置阶段:在这个阶段,会执行所有的编译脚本,同时还会创建project的所有的task,为后一个阶段做准备。
  • 执行阶段:在这个阶段,gradle 会根据传入的参数决定如何执行这些task,真正action的执行代码就在这里。

gradle file tree

对于一个android studio工程,最基本的配置如下:

   MyApp
      ->build.gradle
      ->setting.gradle
      ->[app]
           ->build.gradle

一个项目有一个setting.gradle、包括一个顶层的 build.gradle文件、每个Module 都有自己的一个build.gradle文件。

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

    dependencies {
        // Android 编译工具的类路径
        classpath 'com.android.tools.build:gradle:2.2.2'
    }
}

//定义的属性会被应用到所有 moudle 中,但是为了保证每个项目的独立性,我们一般不会在这里面操作太多共有的东西
allprojects{
    repositories{
        jcenter()
    }
}
  • 每个项目单独的 build.gradle:针对每个moudle 的配置,如果这里的定义的选项和顶层build.gradle定义的相同,后者会被覆盖。典型的 配置内容如下:
//使用Android 程序的gradle插件,该插件提供了Android 编译、测试、打包等等的所有task。
apply plugin: 'com.android.application'

//关于android 的所有特殊配置
android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"
    defaultConfig {
        applicationId "com.torch.easydev.okhttpdemo"
        minSdkVersion 17
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    //定义编译类型,针对每个类型我们可以有不同的编译配置
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

//定义了当前项目需要依赖的其他库
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    ...
}

gradle wrapper

除了以上几个gradle相关的文件,新建一个studio工程,默认还会生成一些和gradle wrapper相关的一些文件:

  MyApp
     ->gradlew
     ->gradlew.bat
     ->gradle
           ->wrapper
                  ->gradle-wrapper.jar
                  ->gradle-wrapper.properties

那这个gradle-wrapper有什么用呢?主要是用于gradle版本的兼容性问题gradlew.bat是一个可执行文件,当开始sync project时,首先会根据gradle-wrapper.properties文件中gradle的版本号去查找本地,如果本地不存在会去网上下载对应的版本。

gradle使用指南

简单了解了gradle的作用和相关文件的结构之后,接下来主要结合项目过程常见的使用场景,来看看具体该如何使用gradle。

导入第三方库或者工程

日常开发过程中,经常会碰到要使用第三方库或者工程做二次开发,这时候免不了要导入,导入步骤为:

File->New->import project
找到对应的project所在的位置,找到顶层的`build.gradle`点击确定即可

导入后常常会碰到一直在sync project,最后更新还不成功。
这时候主要检查以下几个地方:

1、检查gradle-wrapper.properties中的gradle版本号。可以和本地原有项目直接比对,若不同会从网上下载,但默认情况下更新会失败,因为gradle的下载地址被墙了。这时候要不使用代理地址;要不就直接更改为本地已下载完成的gradle版本号。

#Mon Dec 28 10:00:20 PST 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
//更改为本地已下载的gradle版本号
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip

2、检查各个module下的build.gradle文件的android sdk版本号。要和本地的sdk版本号相对应,否则需要更新到当前配置的sdk版本号才行。

android {
    //要和本地sdk版本相对应
    compileSdkVersion 22
    buildToolsVersion '23.0.3'
    ...
    }

3、检查各个module下的build.gradle文件的依赖库版本号

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    //support版本要和sdk manager下载的v7库相对应
    compile 'com.android.support:appcompat-v7:23.3.0'
    testCompile 'junit:junit:4.12'
}

解决上面这些问题后,基本上可以正常导入第三方库或者工程啦。如果还有问题,就要结合实际情况分析了。

eclipse项目迁移到android studio

点击File->New->import project 找到eclipse项目根目录,导入。
这里写图片描述

导入jar包

  1. 将jar包复制到对应工程module的libs文件夹下
  2. 配置build.gradle依赖
dependencies {
    //第一种方法,直接配置编译libs下所有jar包
    compile fileTree(include: ['*.jar'], dir: 'libs')

    //第二种方法,配置对应的jar包
    compile files('libs/AMap_Location_V3.4.0_20170427.jar')
}

添加.so文件

  1. 在libs下新建一个文件夹,名称为armeabi, 将so文件复制到该文件夹下。
  2. 配置build.gradle文件
android {
    ...
     sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }
}

自定义包名及版本号

android {
    ...
    defaultConfig {
        //自定义包名
        applicationId "com.boc.spos.service"
        minSdkVersion 17
        targetSdkVersion 23
        versionCode 4
        //版本号
        versionName "1.0.4"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
}

AndroidManifest.xml文件中也配置包名和版本号时,已build.gradle文件的配置为主。
需要注意的是,在我们曾经定义的AndroidManifest.xml中,那里定义的包名有两个用途:一个是作为程序的唯一识别ID,防止在同一手机装两个一样的程序;另一个就是作为我们R资源类的包名。在以前我们修改这个ID会导致所有用引用R资源类的地方都要修改。但是现在我们如果修改applicationId只会修改当前程序的ID,而不会去修改源码中资源文件的引用。

自定义APK文件名

// rename the apk with the version name
    // add output file sub folder by build type
    applicationVariants.all {
        variant ->
        def time = new java.text.SimpleDateFormat("yyyyMMdd").format(new Date())
        variant.outputs.each { output ->
            output.outputFile = new File(
                    output.outputFile.parent + "/${variant.buildType.name}",
                    "MyApp_${variant.versionName}_${variant.productFlavors[0].name + time}.apk".toLowerCase())
        }
    }

将会生成格式为:MyApp_1.0.0_debug20170527.apk的一个文件

不同签名打包

一个产品,在开发阶段和发布阶段,经常需要使用不同的签名,以前在eclipse要通过导出两次apk来实现这个目的。现在有了gradle,只需要简单配置一下build.gradle,就能实现啦。

android {
     //用于演示,同一个签名
     signingConfigs {
        debug {
            keyAlias RELEASE_KEY_ALIAS
            keyPassword RELEASE_KEY_PASSWORD
            storeFile file(RELEASE_STORE_FILE)
            storePassword RELEASE_STORE_PASSWORD
        }
        release {
            keyAlias RELEASE_KEY_ALIAS
            keyPassword RELEASE_KEY_PASSWORD
            storeFile file(RELEASE_STORE_FILE)
            storePassword RELEASE_STORE_PASSWORD
        }
    }

    buildTypes {
        release {
            signingConfig signingConfigs.release
        }
        debug {
            signingConfig signingConfigs.debug
        }
    }
}

配置gradle.properties文件

RELEASE_KEY_PASSWORD=android
RELEASE_KEY_ALIAS=androiddebugkey
RELEASE_STORE_PASSWORD=android
RELEASE_STORE_FILE=E:/star-net/keystore/test.keystore

多渠道打包

android {
    ...
     productFlavors {
        Inner {
            resValue("string" , "IS_DEBUG_MODE", "true")
        }
        PROC {
            resValue("string" , "IS_DEBUG_MODE", "false")
        }
    }
}

代码中,根据配置好的变量做相应版本的处理

    private static String IS_DEBUG_MODE_GRADLE = HuaxiaBankApplication.getContext().getResources().getString(R.string.IS_DEBUG_MODE);

当然,也可以通过不同的buildConfig来配置不同的版本

android {
     ...
     productFlavors {
        Inner {
           buildConfigField "boolean", "IS_DEBUG", "false"
        }
        PROC {
             buildConfigField "boolean", "IS_DEBUG", "true"
        }
    }
}

同样的在代码中,根据配置好的变量做相应版本的处理

Log.d("MyApp", "开始初始化: IS_DEBUG=" + BuildConfig.IS_DEBUG);

参考资料

Gradle完整指南:http://www.jianshu.com/p/9df3c3b6067a#

装载请注明出处:http://blog.youkuaiyun.com/youyu_torch/article/details/72786723, 谢谢!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值