美文网首页
与Gradle的那些年

与Gradle的那些年

作者: Pin_ZL | 来源:发表于2017-11-27 15:02 被阅读0次

    既然要学习Gradle,首先要知道它是什么,它又能干什么,以及怎么使用它。

    Gradle是什么?

    Gradle 是以Groovy为基础,面向java应用,基于DSL语法的自动化构建工具。
    是google引入,替换ant和maven的新工具,其依赖兼容maven和ivy。
    

    Gradle能干什么?

    1.更容易重用资源和代码;
    2.可以更容易创建不同的版本的程序,多个类型的apk包;
    3.更容易配置,扩展;
    4.更好的IDE集成;
    

    Android Studio中的android项目通常至少包含两个build.gradle文件,一个是project范围的,另一个是module范围的,由于一个project可以有多个module,所以每个module下都会对应一个build.gradle。

    project->build.gradle

    project下的build.gradle是整个project的配置,主要配置gradle 版本及 全局依赖仓库、库或者其他全部参数。android studio 现在重要仓库采用jcenter(),之前版本放在mavenCentral。另外有时还没有加入jcenter()仓库的第三方库,也需要在这里配置他们的库地址。需要在这里配置,才能将第三方库拉下来。

    apply from: "config.gradle"
    buildscript {
        repositories {
            mavenLocal()
            mavenCentral()
            jcenter()
            maven {
                url 'https://jitpack.io'
            }
            maven {
                url 'https://maven.google.com/'
                name 'Google'
            }
        }
        dependencies {
            classpath 'com.android.tools.build:gradle:2.3.3'
            classpath 'com.sensorsdata.analytics.android:android-gradle-plugin2:1.0.2'
            classpath "io.realm:realm-gradle-plugin:4.1.1"
        }
    }
    allprojects {
        repositories {
            mavenLocal()
            mavenCentral()
            jcenter()
            maven {
                url 'https://jitpack.io'
            }
            maven {
                url 'https://maven.google.com/'
                name 'Google'
            }
        }
    }
    

    apply from: "config.gradle" :外部配置文件,下面会讲到
    buildscript和allprojects中都包含有repositories,是因为他们的作用域不同,buildscript中的仓库是gradle脚本自身需要的资源,而allprojects下的仓库是项目所有模块需要的资源。

    config.gradle

    ext {
    
        android = [
                //编译SDK的版本
                compileSdkVersion: 26,
                //buildtool 的版本
                buildToolsVersion: "26.0.2",
                //支持最小android sdk 版本
                minSdkVersion    : 17,
                // 目标版本
                targetSdkVersion : 26
                //应用版本号
                versionCode = 1
                //应用版本名称
                versionName = "v1.0.0"
        ]
    
        dependVersion = [
                support: "26.0.2"
        ]
        //服务器一 路由地址
        serverOneAPIUrl = [
                api_url_debug  : "\"https://devone.gradle.cn/\"",//开发
                api_url_test   : "\"https://testone.gradle.cn/\"",//内测 
                api_url_preview: "\"https://preone.gradle.cn/\"",//预览
                api_url_release: "\"https://one.gradle.cn/\""//正式
        ]
       //服务器二 路由地址
       serverTwoAPIUrl = [
                api_chat_url_debug  : "\"https://devtwo.gradle.cn/\"",//开发
                api_chat_url_test   : "\"https://testtwo.gradle.cn/\"",//内测
                api_chat_url_preview: "\"https://pretwo.gradle.cn/\"",//预览
                api_chat_url_release: "\"https://two.gradle.cn/\""//正式
        ]
        //服务器三 路由地址
        serverThreeUrl = [
                api_url_debug  : "\"https://devthree.gradle.cn/\"",//开发
                api_url_test   : "\"https://testthree.gradle.cn/\"",//内测
                api_url_preview: "\"https://prethree.gradle.cn/\"",//预览
                api_url_release: "\"https://three.gradle.cn/\""//正式
        ]
    
        dependencies = [
                //------------- 分包  ------------
                multidex                  : "com.android.support:multidex:1.0.1",
    
                // ------------- Android -------------
                supportV4                 : "com.android.support:support-v4:${dependVersion.support}",
                appcompatV7               : "com.android.support:appcompat-v7:${dependVersion.support}",
                design                    : "com.android.support:design:${dependVersion.support}",
                cardview                  : "com.android.support:cardview-v7:${dependVersion.support}",
                junit                     : "junit:junit:4.12",
    
                // ------------- reyclerview ------------
                recyclerview              : "com.android.support:recyclerview-v7:${dependVersion.support}",
    
                // ------------- 网络请求 -------------
                retrofit                  : 'com.squareup.retrofit2:retrofit:2.3.0',
                retrofit_rxjava           : 'com.squareup.retrofit2:adapter-rxjava2:2.3.0',
                retrofit_converter_gson   : 'com.squareup.retrofit2:converter-gson:2.3.0',
                okhttp_logging_interceptor: 'com.squareup.okhttp3:logging-interceptor:3.8.0',
    
                // ------------- 图片加载 -------------
                glide                     : 'com.github.bumptech.glide:glide:4.3.1',
                glideAp                     : 'com.github.bumptech.glide:compiler:4.3.1',
    
                // ------------- 通信 -------------
                eventbus                  : 'org.greenrobot:eventbus:3.0.0',
    
                // ------------- RxAndroid -------------
                rxAndroid                 : 'io.reactivex.rxjava2:rxandroid:2.0.1',
                rxJava                    : 'io.reactivex.rxjava2:rxjava:2.0.1',
    
                // ------------- json解析 -------------
                gson                      : 'com.google.code.gson:gson:2.8.1',
        ]
    }
    

    项目配置文件,ext全局变量,在每个module的build.gradle文件中都可以随时引用

    module->build.gradle

    apply plugin: 'com.android.application'
    android {
        compileSdkVersion rootProject.ext.android.compileSdkVersion
        buildToolsVersion rootProject.ext.android.buildToolsVersion
    
        //加载本地配置文件local.properties
        Properties properties = new Properties()
        InputStream inputStream = project.rootProject.file('local.properties').newDataInputStream();
        properties.load(inputStream)
    
        //安卓构建过程需要配置的参数
        defaultConfig {
            applicationId "com.demo.gradle"
            minSdkVersion rootProject.ext.android.minSdkVersion
            targetSdkVersion rootProject.ext.android.targetSdkVersion
            multiDexEnabled true
            versionCode rootProject.ext.android.versionCode
            versionName rootProject.ext.android.versionName
        }
        //ndk配置参数
        ndk {
            abiFilters "armeabi-v7a", "arm64-v8a", "x86"
        }
        //java版本号
        compileOptions {
                sourceCompatibility JavaVersion.VERSION_1_8
                targetCompatibility JavaVersion.VERSION_1_8
        }
        //渠道Flavors_打包
        productFlavors {
            //可以设置不同渠道渠道号,应用名称
            dev { // 开发
                buildConfigField "String", "CHANNEL_NUMBER", '"11111"'
            }
            '360' {
                buildConfigField "String", "CHANNEL_NUMBER", '"11112"'
            }
            GooglePlay {
                buildConfigField "String", "CHANNEL_NUMBER", "11113"'
        }
    
        //定义apk文件名称格式
        applicationVariants.all { variant ->
            variant.outputs.each { output ->
                def outputFile = output.outputFile
                if (outputFile != null && outputFile.name.endsWith('.apk')) {
                    def fileName = outputFile.name.replace(".apk", "-${defaultConfig.versionName}_${releaseFormatTime()}.apk")
                    output.outputFile = new File(outputFile.parent, fileName)
                }
            }
        }
    
        //签名
        signingConfigs {
            release {
                keyAlias properties.getProperty('keyAlias')
                keyPassword properties.getProperty('keyPassword')
                storeFile file(properties.getProperty('storeFile'))
                storePassword properties.getProperty('storePassword')
            }
        }
    
        buildTypes {
            debug {
                minifyEnabled false
                zipAlignEnabled false
                shrinkResources false
                (..各个服务器的dubug路由地址..)
            }
    
             preview {
                debuggable false // 是否保留调试信息
                minifyEnabled true  //是否混淆
                zipAlignEnabled true // 包优化
                shrinkResources true // 移除不必要的资源
                // 签名
                signingConfig signingConfigs.release
                // 代码混淆规则文件
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
                (..各个服务器的preview路由地址..)
            }
    
            release {
                //加上后缀
                applicationIdSuffix ".release"
                minifyEnabled true //是否混淆
                zipAlignEnabled true // zip对齐优化
                shrinkResources true // 移除不必要的资源
    
                // 不显示Log
                buildConfigField "boolean", "LOG_DEBUG", "false"
    
                // 签名
                signingConfig signingConfigs.release
                //混淆文件的位置
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
                (..各个服务器的release路由地址..)
            }
        }
    
        // 为了解决部分第三方库重复打包了META-INF的问题
        packagingOptions {
            exclude 'META-INF/ASL2.0'
            exclude 'META-INF/LICENSE'
            exclude 'META-INF/NOTICE'
            exclude 'META-INF/MANIFEST.MF'
            exclude 'sign.properties'
            exclude 'keystore.jks'
        }
    
        //执行lint检查,有任何的错误或者警告提示,都会终止构建,我们可以将其关掉。
        lintOptions {
            abortOnError false
        }
       
        dataBinding {
            enabled = true
        }
    
        dexOptions {
            //支持最大工程模式
            jumboMode = true 
            javaMaxHeapSize "10g"
            //使用增量模式
            //incremental false
    
            preDexLibraries = false //预编译
            threadCount = "8" //线程数目
        }
    
    }
    //定义打包时间格式化
    def releaseFormatTime() {
        return new Date().format("yyyy-MM-dd HH:mm", TimeZone.getDefault())
    }
    
    // 发布的日更新包时间尾巴
    def releaseFormatDayTime() {
        return new Date().format("yyyy-MM-dd", TimeZone.getDefault())
    }
    // 定义打包时间戳
    def releaseTime() {
        return new Date().getTime();
    }
    
    repositories {
        flatDir {
            dirs 'aars'
        }
        maven {
            url 'https://maven.google.com/'
            name 'Google'
        }
    }
    dependencies {
        compile fileTree(include: ['*.jar'], dir: 'libs')
        compile rootProject.ext.dependencies.multidex
        compile rootProject.ext.dependencies.bugtags
        //------------  Android support  -----------
        //compile rootProject.ext.dependencies.supportV4
        compile rootProject.ext.dependencies.design
        compile rootProject.ext.dependencies.appcompatV7
        compile rootProject.ext.dependencies.cardview
        //------------  recyclerview  -------------
        compile rootProject.ext.dependencies.recyclerview
        compile rootProject.ext.dependencies.recyclerview_divider
        //------------  通信  --------------
        compile rootProject.ext.dependencies.eventbus
        //------------  网络  ----------
        compile project(':api')
        //------------  rxAndroid-----------
        compile rootProject.ext.dependencies.rxAndroid
        compile rootProject.ext.dependencies.topsnackbar
        compile rootProject.ext.dependencies.glide
        annotationProcessor rootProject.ext.dependencies.glideAp
    }
    

    1.buildTypes是指建构的类型,一般只用两种默认类型 debug 和 release,顾名思义 debug 用来配置开发过程中的一些内容;release 用来配置正式发布版本的内容。有时我们需要发布介于debug与release之间的preview 版本。
    2.签名信息,可以直接将信息写到gradle.properties或者,然后在然后在build.gradle中引用即可。
    3.多渠道的关键在于定义不同的product flavor。这里的flavor名如果是数字开头,必须用引号引起来。

    BuildConfig

    在build.gradle中配置buildConfigField参数,编译后会在..\app\build\generated\source\buildConfig文件夹下会自动生成对应版本对应module的BuildConfig.java。BuildConfig就会包含对应版本的配置信息。程序中可以直接引用这些数据。例如BuildConfig.DEBUG。

    public final class BuildConfig {
      public static final boolean DEBUG = Boolean.parseBoolean("true");
      public static final String APPLICATION_ID = "com.demo.gradle";
      public static final String BUILD_TYPE = "debug";
      public static final String FLAVOR = "wandoujia";
      public static final int VERSION_CODE = 1;
      public static final String VERSION_NAME = "v1.0.0_debug";
      public static final int BUILD_TYPE_INT = 0;
      public static final boolean IS_DEBUG = true;
      (..各个服务器路由地址..)
    }
    

    module 调整目录结构sourceSets

    默认情况下,java文件和resource文件分别在src/main/java和src/main/res目录下,在build.gradle文件,andorid{}里面添加下面的代码,便可以将java文件和resource文件放到src/java和src/resources目录下。

    sourceSets {
       min.java.srcDirs = ['src/java']
       min.resources.srcDirs = ['src/resources']
    }
    

    Gradle常用命令

    ./gradlew, ./代表当前目录,gradlew代表 gradle wrapper,意思是gradle的一层包装,大家可以理解为在这个项目本地就封装了gradle,即gradle wrapper, myAPP/gradle/wrapper/gralde-wrapper.properties**文件中声明了它指向的目录和版本。只要下载成功即可用grdlew wrapper的命令代替全局的gradle命令。

    理解了gradle wrapper的概念,下面一些常用命令也就容易理解了。

    ./gradlew 下载更新gradle
    ./gradlew -v 版本号
    ./gradlew assemble 构建项目输出
    ./gradlew check 运行检测和测试任务
    ./gradlew clean 清除9GAG/app目录下的build文件夹
    ./gradlew build 运行check和assemble,检查依赖并编译打包
    这里注意的是 ./gradlew build 命令把debug、release环境的包都打出来,如果正式发布只需要打Release的包,该怎么办呢,下面介绍一个很有用的命令 assemble<build type="" name="">, 如</build>
    ./gradlew assembleDebug 编译并打Debug包
    ./gradlew assembleRelease 编译并打Release的包所有渠道的
    ./gradlew assembleWandoujiaRelease 编译并打包豌豆荚的Release版本
    ./gradlew assembleWandoujia 编译并打包豌豆荚的所有版本
    ./gradlew installRelease Release模式打包并安装
    ./gradlew uninstallRelease 卸载Release模式包

    相关文章

      网友评论

          本文标题:与Gradle的那些年

          本文链接:https://www.haomeiwen.com/subject/khxdbxtx.html