Gradle Task的使用

一、背景

我们的项目打包APK前需要根据业务需要更改AndroidManifest文件内容和替换so文件来生成不同的apk。这样就需要手动来做这些事情以实现对应的需求。

手动修改的弊端
1.因为改动地方比较多,所以很容易出错或出现遗漏。
2.改动需要时间,生产效率低下。
3.对于不熟悉业务的人来说,修改起来比较困惑。

那既然这样有没有一种方法,通过一些指令来完成这些既繁琐又容易出错的重复性手工作业呢,这就是今天要介绍的Gradle Task了。

二、Task介绍

一个Task代表一个构建工作的原子操作,例如编译calsses或者生成javadoc。
Gradle中,每一个待编译的工程都叫一个Project。每一个Project在构建的时候都包含一系列的Task。比如一个Android APK的编译可能包含:Java源码编译Task、资源编译Task、JNI编译Task、lint检查Task、打包生成APK的Task、签名Task等。插件本身就是包含了若干Task的。
如下就是一个task的简单例子:

task hello {
        println 'Hello world!'
}

在AS的Terminal窗口输入命令

xxx\xxx>gradlew hello

执行结果如下:

Hello world!                           

BUILD SUCCESSFUL     

Total time: 2.163 secs   

更多用法
task myTask
task myTask { configure closure } // closure是一个闭包
task myType << { task action } // <<符号是doLast的缩写
task myTask(type: SomeType) // SomeType可以指定任务类型,Gradle本身提供有Copy、Delete、Sync等
task myTask(type: SomeType) { configure closure }

  • 一个Task包含若干Action。所以,Task有doFirst和doLast两个函数,用于添加需要最先执行的Action和需要和需要最后执行的Action。Action就是一个闭包。闭包,英文叫Closure,是Groovy中非常重要的一个数据类型或者说一种概念。
  • Task创建的时候可以通过 type: SomeType 指定Type,Type其实就是告诉Gradle,这个新建的Task对象会从哪个基类Task派生。比如,Gradle本身提供了一些通用的Task,最常见的有Copy 任务。Copy是Gradle中的一个类。当我们:task myTask(type:Copy)的时候,创建的Task就是一个Copy Task。
  • 当我们使用 taskmyTask{ xxx}的时候,花括号就是一个closure。
  • 当我们使用taskmyTask << {xxx}的时候,我们创建了一个Task对象,同时把closure做为一个action加到这个Task的action队列中,并且告诉它“最后才执行这个closure”

Task的API文档:https://docs.gradle.org/current/dsl/org.gradle.api.Task.html

三、代码实现

替换AndroidManifest文件

task chVer(type: Copy) { // 指定Type为Copy任务
    from "src/main/manifest/AndroidManifestCopy.xml"  // 复制src/main/manifest/目录下的AndroidManifest.xml
    into 'src/main'  // 复制到指定目标目录
    rename { String fileName -> //在复制时重命名文件
        fileName = "AndroidManifest.xml" // 重命名
    }

}

替换so文件

task chSo(type: Copy) {
    from "src/main/jniLibs/test"   // 复制test文件夹下的所有so文件
    into "src/main/jniLibs/armeabi-v7a" //复制到armeabi-v7a文件夹下
}

这样每次打包APK前执行以上任务就可以自动替换文件啦!

问:那如果有多个任务需要执行是不是要执行多次任务呢?
答:可以通过多任务命令调用一次即可。

gradlew task1 task2 [...]

问:任务名太长不想输入这么多字怎么办?
答:可以采用简化操作,但是必须保证可以唯一区分出该任务的字符,如:

gradlew cV

问:那我不想每次打包前都输入命令怎么办?
答:可以每次build时自动执行自定义任务。

afterEvaluate {
    tasks.matching {
        // 以process开头以ReleaseJavaRes或DebugJavaRes结尾的task
        it.name.startsWith('process') && (it.name.endsWith('ReleaseJavaRes') || it.name.endsWith
                ('DebugJavaRes'))
   }.each { task ->
        task.dependsOn(chVer, chSo)  // 任务依赖:执行task之前需要执行dependsOn指定的任务
    }
}

完整的build.gradle代码:

apply plugin: 'com.android.application'

android {

    compileSdkVersion 23
    buildToolsVersion "23.0.3"


    defaultConfig {
        applicationId "com.skr.voip"
        minSdkVersion 15
        targetSdkVersion 19
    }

    buildTypes {

        debug {
            minifyEnabled false
        }

        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }
}

dependencies {
    //    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:support-v4:23.4.0'
    ...
   
}

task chVer(type: Copy) {
    from "src/main/manifest/AndroidManifestCopy.xml"  // 复制src/main/manifest/目录下的AndroidManifest.xml
    into 'src/main'  // 复制到指定目标目录
    rename { String fileName -> //在复制时重命名文件
        fileName = "AndroidManifest.xml" // 重命名
    }

}

task chSo(type: Copy) {
    from "src/main/jniLibs/test"   // 复制test文件夹下的所有文件
    into "src/main/jniLibs/armeabi-v7a" //复制到armeabi-v7a文件夹下
}

afterEvaluate {
    tasks.matching {
        // 以process开头以ReleaseJavaRes或DebugJavaRes结尾的task
        it.name.startsWith('process') && (it.name.endsWith('ReleaseJavaRes') || it.name.endsWith
                ('DebugJavaRes'))
   }.each { task ->
        task.dependsOn(chVer, chSo)  // 任务依赖:执行task之前需要执行dependsOn指定的任务
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

互联网小熊猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值