zoukankan      html  css  js  c++  java
  • Android -- Gradle

    使用gradle的目的                                                                     

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

    Gradle基本结构                                                                       

    使用ide创建的gradle构建的项目,会自动创建一个build.gradle,如下:

    buildscript {
        repositories {
            mavenCentral()
        }
     
        dependencies {
            classpath 'com.android.tools.build:gradle:0.9.0'
        }
    }
     
    apply plugin: 'android'
     
    android {
        compileSdkVersion 19
        buildToolsVersion "19.0.0"
    }

    可以看到,构建文件主要有三个区域:

    buildscript{…}
    
    //Configures the build script classpath for this project. 设置脚本的运行环境
    
    apply plugin: 'android'
    
    //设置使用android插件构建项目
    
    android{…}
    
    //设置编译android项目的参数

    任务task的执行                                                                       

    • assemble The task to assemble the output(s) of the project(输出一个项目文件,android就是打包apk)
    • check The task to run all the checks.(运行检查,检查程序的错误,语法,等等)
    • build This task does both assemble and check (执行assemble和check)
    • clean This task cleans the output of the project(清理项目输出文件)

    上面的任务assemble,check,build实际上什么都不做,他们其实都是其他任务的集合。

    执行一个任务的方式为gradle 任务名, 如gradle assemble,在android项目中还有connectedCheck(检查连接的设备或模拟器),deviceCheck(检查设备使用的api版本)。通常我们的项目会有至少生成两个版本,debug和release,我们可以用两个任务assembleDebug和assembleRelease去分别生成两个版本,也可以使用assemble一下子生成两个版本。gradle支持任务名缩写,在我们执行gradle assembleRelease的时候,可以用gradle aR代替。

    基本的构建定制                                                                       

    我们可以在build.gradle文件中配置我们的程序版本等信息,从而可以生成多个版本的程序。
    支持的配置有:

    • minSdkVersion 最小支持sdk版本
    • targetSdkVersion 编译时的目标sdk版本
    • versionCode 程序版本号
    • versionName 程序版本名称
    • packageName 程序包名
    • Package Name for the test application 测试用的程序包名
    • Instrumentation test runner 测试用的instrumentation实例
    android {
        compileSdkVersion 19
        buildToolsVersion "19.0.0"
     
        defaultConfig {
            versionCode 12
            versionName "2.0"
            minSdkVersion 16
            targetSdkVersion 16
        }
    }

    目录配置                                                                              

    默认情况下项目目录是这样的
    有两个组件source sets,一个main,一个test,对应下面两个文件夹。

    src/main/ 
    src/androidTest/

    然后对于每个组件目录都有两个目录,分别存储java代码和资源文件

    java/ 
    resources/

    对于android项目中呢,对应的目录和文件是
    AndroidManifest.xml //该文件src/androidTest/目录下不需要,程序执行时会自动构建

    res/ 
    assets/ 
    aidl/ 
    rs/ 
    jni/

    如果需要上面这些文件,但是不是在上面所说的目录,则需要设置。

    sourceSets {
        main {
            java {
                srcDir 'src/java'
            }
            resources {
                srcDir 'src/resources'
            }
        }
    }

    可以给main或者test设置根目录,如

    sourceSets {
            androidTest.setRoot('tests')
        }

    可以指定每种文件的存储路径

    sourceSets {
            main {
                manifest.srcFile 'AndroidManifest.xml'
                java.srcDirs = ['src']
                resources.srcDirs = ['src']
                aidl.srcDirs = ['src']
                renderscript.srcDirs = ['src']
                res.srcDirs = ['res']
                assets.srcDirs = ['assets']
            }
        }

    特别是我们的ndk生成的.so文件,通常我们不是放到jni目录中的,我们需要设置一下

    sourceSets {
            main {
                jniLibs.srcDirs = ['libs']
            }
        }

    签名配置                                                                              

    可以给不同类型进行不同的配置:

    android {
        signingConfigs {
            debug {
                storeFile file("debug.keystore")
            }
     
            myConfig {
                storeFile file("other.keystore")
                storePassword "android"
                keyAlias "androiddebugkey"
                keyPassword "android"
            }
        }
     
        buildTypes {
            foo {
                debuggable true
                jniDebugBuild true
                signingConfig signingConfigs.myConfig
            }
        }
    }

    上面的配置文件配置两个类型,一个时debug类型,一个时自己的自定义类型。两个分别使用了不同的签名,同时对于生成密钥,要填写设置的密码。代码混淆设置代码混淆设置代码混淆设置

    代码混淆设置                                                                         

    android {
        buildTypes {
            release {
                runProguard true
                proguardFile getDefaultProguardFile('proguard-android.txt')
            }
        }
    }

    以上是使用默认的proguard文件去进行混淆,也可以使用自己编写的规则进行混淆,proguardFile 'some-other-rules.txt'

    依赖配置                                                                              

    程序中会依赖别的包,或者程序,需要引入别的类库。前面也说到了,支持maven。
    对于本地的类库,可以这样引入:

    dependencies {
        compile files('libs/foo.jar')   //单个文件
        compile fileTree(dir: 'libs', include: ['*.jar'])  //多个文件
    }
     
    android {
        ...
    }

    对于maven仓库文件:

    repositories {
        mavenCentral()
    }
     
     
    dependencies {
        compile 'com.google.guava:guava:11.0.2'
    }
     
    android {
        ...
    }

    输出不同配置的应用                                                                  

    android {
        ...
     
        defaultConfig {
            minSdkVersion 8
            versionCode 10
        }
     
        productFlavors {
            flavor1 {
                packageName "com.example.flavor1"
                versionCode 20
            }
     
            flavor2 {
                packageName "com.example.flavor2"
                minSdkVersion 14
            }
        }
    }

    通过以上设置,我们可以输出不同的保命不同的版本号,以及最小sdk的程序包。当然我们可以根据自己的需求去做其他的不同。

    生成多个渠道包                                                                       

    buildscript {
        repositories {
            mavenCentral()
        }
        dependencies {
            classpath 'com.android.tools.build:gradle:0.9.+'
        }
    }
    apply plugin: 'android'
     
    repositories {
            mavenCentral()
    }
     
    android {
        compileSdkVersion 19
        buildToolsVersion "19.0.3"
     
        defaultConfig {
            minSdkVersion 8
            targetSdkVersion 19
            versionCode 1
            versionName "1.0"
        }
     
        sourceSets {
            main {
                jniLibs.srcDirs = ['libs']
            }
        }
     
        lintOptions {
            abortOnError false
        }
     
     
    //签名
        signingConfigs {
            //你自己的keystore信息
            release {
                storeFile file("×.keystore")
                storePassword "×××"
                keyAlias "××××"
                keyPassword "×××"
            }
        }
     
        buildTypes {
     
            debug {
                signingConfig signingConfigs.release
            }
     
            release {
                signingConfig signingConfigs.release
                runProguard false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
            }
        }
     
        //渠道Flavors,我这里写了一些常用的,你们自己改
        productFlavors {
            //GooglePlay{}
            //Store360{}
            //QQ{}
            //Taobao{}
            //WanDouJia{}
            //AnZhuo{}
            //AnZhi{}
            //BaiDu{}
            //Store163{}
            //GFeng{}
            //AppChina{}
            //EoeMarket{}
            //Store91{}
            //NDuo{}
            xiaomi{}
            umeng{}
        }
     
    }
     
     
    //替换AndroidManifest.xml的UMENG_CHANNEL_VALUE字符串为渠道名称
    android.applicationVariants.all{ variant ->
        variant.processManifest.doLast{
     
            //之前这里用的copy{},我换成了文件操作,这样可以在v1.11版本正常运行,并保持文件夹整洁
            //${buildDir}是指./build文件夹
            //${variant.dirName}是flavor/buildtype,例如GooglePlay/release,运行时会自动生成
            //下面的路径是类似这样:./build/manifests/GooglePlay/release/AndroidManifest.xml
            def manifestFile = "${buildDir}/manifests/${variant.dirName}/AndroidManifest.xml"
     
            //将字符串UMENG_CHANNEL_VALUE替换成flavor的名字
            def updatedContent = new File(manifestFile).getText('UTF-8').replaceAll("UMENG_CHANNEL_VALUE", "${variant.productFlavors[0].name}")
            new File(manifestFile).write(updatedContent, 'UTF-8')
     
            //将此次flavor的AndroidManifest.xml文件指定为我们修改过的这个文件
            variant.processResources.manifestFile = file("${buildDir}/manifests/${variant.dirName}/AndroidManifest.xml")
        }
    }

    以上的功能就是替换我的Manifest中的渠道标示,同时去生成不同的apk包。

    最后说明                                                                              

    程序在buid的时候,会执行lint检查,有任何的错误或者警告提示,都会终止构建,我们可以将其关掉。

    lintOptions {         abortOnError false     }

    我是天王盖地虎的分割线                                                             

    参考:http://www.open-open.com/lib/view/open1401084786792.html

  • 相关阅读:
    了解 NoSQL 的必读资料
    关于什么时候用assert(断言)的思考
    这次见到了一些大侠
    NetBeans 时事通讯(刊号 # 87 Jan 12, 2010)
    动态链接库dll,静态链接库lib, 导入库lib
    新女性十得 写得了代码,查得出异常
    记录系统乱谈
    新女性十得 写得了代码,查得出异常
    fullpage.js禁止滚动
    RunningMapReduceExampleTFIDF hadoopclusternet This document describes how to run the TFIDF MapReduce example against ascii books. This project is for those who wants to experiment hadoop as a skunkworks in a small cluster (110 nodes) Google Pro
  • 原文地址:https://www.cnblogs.com/yydcdut/p/4162440.html
Copyright © 2011-2022 走看看