AndroidStudio使用Gradle-高级篇

来源:互联网 发布:centos 7 ant 编辑:程序博客网 时间:2024/05/18 03:52

上一篇AndroidStudio使用Gradle-基础篇还留下了gradle一些比较实用的点没有介绍,这里介绍下其他细节。

相关资料

  • Gradle Plugin for Android 类参考
    http://dcow.io/android-gradle-plugin-docs/overview-summary.html
  • android Gradle build-system 源码
    https://android.googlesource.com/platform/tools/base/+/gradle_2.0.0/build-system/

多渠道打包

安卓的应用市场,不像苹果那样只有一个appstore,自从google被墙以后,国内的应用市场风生水起,应用市场是一个很大的流量入口,只要站在风口,猪也能飞起来。流量就是风。当下国内做的比较好的应用市场,有豌豆荚,360(安全卫士绑定),百度(搜索绑定),应用宝(QQ绑定),后三者都是有点流氓的做法。为了统计不同应用市场的相关下载使用数据,所以多渠道成为一种必然。

1、配置AndroidManifext.xml
这里配置的目的,可以通过javacode找到Metadata配置的渠道值。目前友盟统计是国内现阶段应用分析做的比较好的。所以这里也贴下友盟的配置,当然有后台的自己统计也行,一般做法,就是在application的oncreate的时候可以通过packageInfo读取设定的相关配置上传服务器。

//UMENG_CHANNEL是文档指定配置渠道名的字段,//${UMENG_CHANNEL_VALUE}是占位符,在后面gradle中指定相关内容<meta-data   android:name="UMENG_CHANNEL"   android:value="${UMENG_CHANNEL_VALUE}" />

2、 在app的gradle中添加渠道配置可以敲代码直接添加,当然也可以通过配置工具project structure进行配置

android  {    productFlavors {        //豌豆荚的渠道配置        wandoujia{            //一些相关配置            minSdkVersion 15            //此id可以不同渠道号不同            applicationId 'com.myapplication.app'            proguardFile 'proguard-project.txt'            targetSdkVersion 23            versionCode 1000000            versionName '1.0.0'        }        yingyongbao{            //同上        }     }}

3、 将gradle配置值给AndroidManifext.xml中的meta-data占位符${umeng_channel_value}
productFlavors.each是对所有渠道的一个遍历,括号里面的内容是一个闭包,flavor代表参数,也就是遍历的渠道,这里的manifestPlaceholders字面理解就是manifest中的占位符。很遗憾找了很久gradle的源码,仅仅只看到了,manifestPlaceholders是ProductFlavor父类BaseConfigImpl的一个map类型的成员变量,目前的作用是[key,value]中的key能替换在menifest中的占位符${key},但必须名称一样。

android  {   productFlavors {    //同上   }   productFlavors.each {          flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: flavor.name]    }}

4、 执行打包
打开as下面的终端,输入打包命令

gradlew assemblerelease

task任务

gradle的一块大的组成,task任务。build.gradle是构建脚本文件,当运行gradle命令的时候会从当前目录查找build.gradle文件来执行构建。所以我们可以在gradle添加相关的task,来定义任务。可以通过as面板的右上角那个Gradle点进去查看tasks。如下图所示
这里写图片描述

常用task
  1. assemble
    assemble任务通常用来打包apk,但不运行单元测试,一般在命令行中输入 gradle assembleDebug,如果是多渠道,可以直接加渠道名,如assembleYingyongbao
  2. check
    check任务包含了项目中所有验证相关的任务,比如运行测试的任务
  3. build
    build任务包含了check和assemble,也就是编译输出
  4. clean
    clean任务会删除build目录,移除所有构建的文件
  5. deviceCheck
    连接设备并运行检查
自定task
  1. 在gradle中编写代码
 task sayhello << {        println 'Hello world!'    }
  1. 通过命令行调用代码
//q 是 quiet 的简写,意思是要安静、干净的输出。如果不加 -q 则会输出日志gradle -q sayhello
  1. 查看项目的所有task任务信息
 gradle tasks //本地安装gradle可以直接使用gradle命令 gradlew tasks //本地未安装可以项目自带的gradlew命令

gradle中使用groovy脚本

gradle是基于groovy语言的,所以能够在gradle中能够使用groovy语言,特别是在build.gradle通过使用groovy来添加相关的处理逻辑。如批量修改应用名称.
这里有篇帖子写深入理解Gradle里面有讲Groovy的语法等待很多细节内容,感兴趣的可以看看深入理解Gradle,这篇文章很详细,当然如果有兴趣也能自建gradle文件,写一个工具脚本,然后通过apply引入。但是这里只对Variants操作tasks相关的操作简单介绍,详细的建议去看博客。
如果还想深入了解的gradle可以参考极客学院的文档Gradle用户指南

Variants种类
  • applicationVariants(只适用于app plugin,也就是安装包的gradle中使用)
  • libraryVariants(只适用于library plugin,也就是库工程的gradle中使用)
  • testVariants(都适用,但由于和测试相关目前接触很少)
Variants的属性介绍

这里写图片描述
这里写图片描述

applicationVariants常用场景

更改release输出的名称

//groovy中def 定义方法和变量都能用def define,每句语句可以省略 分号;def buildTime() {    def date = new Date()    def formattedDate = date.format('yyyyMMdd')    return formattedDate}android {    buildTypes {        release {           /****            *通过类参考和部分源码个人感觉applicationVariant是            *ApplicationVariantImpl可以通过反射调用类中的相关信息,实际上数据保存            *ApplicationVariantImpl中的ApplicationVariantData中,            *ApplicationVariantImpl实现的是BseVariant接口,所以BaseVariant接口中            *的getXXX方法我们都应该可以通过直接variant.XXX获取到相应的值。           **/            //each就是一个groovy中的遍历方法,后面{}中是一个闭包,->            //前面的是传入参数,变种variant,variant            applicationVariants.each { variant ->            //Returns the variant outputs. There should always be at least one             //output.这个是BaseVariant方法中getOutputs()的解释。            //遍历这个输出,app的输出肯定有apk                variant.outputs.each { output ->                    if (output.outputFile != null && output.outputFile.name.endsWith('.apk')                        &&'release'.equals(variant.buildType.name)) {                       //将输出的apk名称更改                        def apkFile = new File(                                output.outputFile.getParent(),    "app_${variant.flavorName}_v${variant.versionName}_${buildTime()}.apk")                        output.outputFile = apkFile                    }                }            }        }    }}
0 0
原创粉丝点击