Android解放双手之Gradle自动化打包实战

https://www.jianshu.com/u/0111a7da544b

前言

解放双手,双击桌面快捷方式生成apk包,基于Gradle、bat文件让开发人员告别打包烦扰!

前不久有一个Unity3D研发的小仙女在羽毛球场问我关于Android Studio打apk的一些事情,她说他们运营和测试隔三差五的就坐着她旁边要她重复性的打包(估计是那群痴汉打着工作的幌子实际上干着撩妹的活惹火了这位认真敬业的小姐姐),那么有没有省力一点的办法快速打包?

一直以来,对于某些频繁进行打包工作的业务部开发人员来说,打包工作不仅繁琐冗余而且费时费力。如何快速、高效的解决频繁出包以及提高生产效率解放生产力是我们一直在思考的问题。有没有一种办法比如我只想要双击桌面快捷方式然后就打包成APK 接着在保存到自定义盘符路径?  答案是有的。我们知道Android Studio是基于Gradle来进行快速构建项目,Gradle本质是一个基于Apache Ant和Apache Maven概念的项目自动化构建工具。 由于一些论坛上的文章是基于Android2.X版本来进行解释说明但是笔者通过这几天的实战(Android Studio版本是3.0以上)发现网上的一些办法已经用不了且新版本自然而然增加了一些之前未提及的新特性,所以本文主要是针对Android Studio3.0版本以上以及Gradle进行一些基本的内容介绍以及如何通过组合技巧实现快速打包;以及针对某一些特定的开发场景如何通过 Java + Gradle去思考并解决问题)。

PS:文章使用到的源码请见末尾。

正文

首先是笔者个人开发环境:

  • JDK:1.8.0_71

  • Android Studio:3.0

  • PC系统:Win7

由于我们这里是基于Gradle进行后面的操作,所以我们首先需集成下Gradle的环境变量(前提是需要配置好JDK)如何配置Gradle环境?由于AndroidStudio里面内置了Gradle,这里我就快速提供Gradle环境配置方案(当然也可以自行谷歌或者百度)。

步骤一:找到自己Android Studio目录下的gradle文件。这是笔者的Android Studio目录下的gradle文件路径:  C:\ProgramFiles\Android\Android Studio\gradle\gradle-4.1\bin 找到这个目录以后,按照配置JDK那样首先将其编辑到系统变量 GRADLE_HOME:

步骤二:步骤一完成以后将 GRADLE_HOME 添加到系统变量,如下图

上面两个步骤执行完毕以后。我们可以测试下Gradle环境是否安装成功。首先打开cmd命令窗口  输入 gradle (第一次会比较慢)出现以下信息即为成功。或者在命令窗口 输入 gradle -version 如果可以显示版本信息即为环境配置成功。

环境配置好以后,我们先回到Android Studio上面。使用Android Studio新建一个项目的时候,(将工具视图切换成Android 也就是下面的红色矩形)系统会为我们自动生成2个build.gradle文件。

Android开发一般将图上的绿色矩形描述为项目的gradle,将黄色矩形称为app.gradle。首先我们看下项目的gradle:

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {repositories {google()jcenter()}dependencies {classpath 'com.android.tools.build:gradle:3.0.0'// NOTE: Do not place your application dependencies here; they belong// in the individual module build.gradle files}
}
allprojects {repositories {google()jcenter()}
}
task clean(type: Delete) {delete rootProject.buildDir
}

首先,这里的两段英文注释写的非常好,翻译过来就是:( Top-level build file ......)顶级构建文件,可以在所有子项目/模块中添加常见的配置选项;(NOTE: Do not place ......)注意:不要将你的应用程序依赖项放在这里;它们属于单独的模块构建 .gradle文件。

我们知道Project.gradle文件主要是全局的gradle构建脚本,这里的jcenter()、google()代码,表示的是引用托管仓库的名称;这里的classpath主要是申明插件的版本号(这里的版本号就是3.0.0)。总体来说项目的gradle文件是顶层的配置文件,部分依赖使用也会在这里进行对应的配置。

看完了最顶层的gradle文件在来看看app的gradle文件,这个文件是我们经常打交道的地方,配置签名信息,渠道信息,配置各种第三方库以及依赖等等。比如这个文件有我们最大的android { }标签以及配置依赖的dependencies{ }标签。dependencies标签里面就是应用内使用到的各种依赖比如我们的OkHttp、Glide等等;关于android{ }的配置因为内容较多,下面是在网上收集到的该标签内的一些标签资料:

  • defaultConfig{ } 默认配置,是ProductFlavor类型。它共享给其他ProductFlavor使用

  • sourceSets{ } 源文件目录设置,是AndroidSourceSet类型。

  • buildTypes{ } BuildType类型

  • signingConfigs{ } 签名配置,SigningConfig类型

  • productFlavors{ } 产品风格配置,ProductFlavor类型

  • testOptions{ } 测试配置,TestOptions类型

  • aaptOptions{ } aapt配置,AaptOptions类型

  • lintOptions{ } lint配置,LintOptions类型

  • dexOptions{ } dex配置,DexOptions类型

  • compileOptions{ } 编译配置,CompileOptions类型

  • packagingOptions{ } PackagingOptions类型

  • jacoco{ } JacocoExtension类型。 用于设定 jacoco版本

  • splits{ } Splits类型

下面就是开始Gradle文件的常用配置:

占位符

在使用友盟进行渠道统计常用的做法是使用占位符,比如我们可以在AndroidManifest.xml文件使用meta-data进行信息的配置。

<!--占位符-->
<meta-dataandroid:name="UMENG_CHANNEL"android:value="${UMENG_CHANNEL}"/>

然后使用的话,如下:

android {compileSdkVersion 26defaultConfig {applicationId "fyqst.huawei"minSdkVersion 15targetSdkVersion 26versionCode 1versionName "1.0"//配置dimensionflavorDimensions "pack"testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"//占位符manifestPlaceholders = [UMENG_CHANNEL: "example"]//NDK的配置ndk { abiFilters "armeabi", "armeabi-v7a", "x86", "mips" }}
}

其中这里的manifestPlaceholders后面的value就是我们声明的属性值。

签名

签名,是android标签内大家经常使用到的,由于Android 7.0加入了新的签名机制(也就是V2签名)针对这个问题的解决方式可以参考这篇文章 Android-V1、V2签名,文章地址如下:

https://www.jianshu.com/p/332525b09a88

因此我们可以直接在debug和release标签中加入v1SigningEnabledtrue 、v2SigningEnabled true 规避使用风险。下面是加入新签名机制以及原来大家比较熟悉的写法:

 signingConfigs {debug {storeFile file('../sharepack.jks')storePassword "123456"keyAlias "sharepack"keyPassword "123456"v1SigningEnabled truev2SigningEnabled true}release {storeFile file('../sharepack.jks')storePassword "123456"keyAlias "sharepack"keyPassword "123456"v1SigningEnabled truev2SigningEnabled true}
}

这里还给大家提供一种关于签名信息的写法(拓展性比第一种较强),首先,我们在app文件的根目录下定义一个文件 signing.properties ,然后写上具体的属性值 (具体的说明如代码截图)

由于Gradle是一门脚本,既然是脚本那么它肯定内置了一些函数(注意:Gradle的函数是在app gradle文件内置的标签外 进行编写)给我们操作调用。因为将签名信息写到了这里的配置文件,所以可以通过Gradle去读取信息 然后进行赋值,代码如下:

//读取签名配置文件
def getSigningProperties() {def propFile = file('signing.properties')if (propFile.canRead()) {def Properties props = new Properties()props.load(new FileInputStream(propFile))if (props != null && props.containsKey('STORE_FILE') && props.containsKey('STORE_PASSWORD') &&props.containsKey('KEY_ALIAS') && props.containsKey('KEY_PASSWORD')) {android.signingConfigs.release.storeFile = file(props['STORE_FILE'])android.signingConfigs.release.storePassword = props['STORE_PASSWORD']android.signingConfigs.release.keyAlias = props['KEY_ALIAS']android.signingConfigs.release.keyPassword = props['KEY_PASSWORD']} else {println 'signing.properties found but some entries are missing'android.buildTypes.release.signingConfig = null}} else {println 'signing.properties not found'android.buildTypes.release.signingConfig = null}
}

既然有了读取签名文件的函数,那我们就可以进行Alias、password的赋值。因此可以在signingConfigs标签内这样写:

 signingConfigs {debug {v1SigningEnabled truev2SigningEnabled true}release {storeFilestorePasswordkeyAliaskeyPasswordv1SigningEnabled truev2SigningEnabled true}}getSigningProperties()

多渠道包配置

AndroidStudio给我们提供的多渠道打包方案是使用productFlavors标签配置渠道信息,但是新版本下直接使用这个productFlavors标签会报错,工具要求我们在defaultConfig标签下新增flavorDimensions,如果不使用flavorDimensions关键字,编译会报错:

自定义apk输出路径

传统的打包操作流程执行编译以及签名后生成的apk默认是 项目\build\outputs\apk 这个路径下面,那现在我想指定apk输出的文件位置(比如我现在想让这个apk输出到 c盘下面的out_apk文件夹下)该如何操作?我们可以在buildTypes 标签下,新增如下代码:

 //其他设置buildTypes {release {minifyEnabled falsesigningConfig signingConfigs.releaseproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}debug {debuggable true  //启用debug的buildType配置}//输出类型applicationVariants.all {//判断是release还是debug版本def buildType = it.buildType.name//获取当前时间的"YYYY-MM-dd"格式。def createTime = new Date().format("YYYY-MM-dd", TimeZone.getTimeZone("GMT+08:00"))//如果是正式包,将其输入到指定文件夹if (buildType == "release") {it.getPackageApplication().outputDirectory = new File('C:\\out_apk'+ "/${it.productFlavors[0].applicationId}/${createTime}")}}}

其中,这里的 new File('C:\\out_apk'......就是自定义的路径,所以你可以任意拓展。Ps:这里的buildTypes标签需要写在signingConfigs标签后面,否则很容易编译错误,这个是笔者遇到过的问题。

好了,说了这么多gradle文件的配置,下面就开始我们的打包工作。

首先是我们的传统打签名包:

点击Android Studio 顶部Tab , Build  —— Generate Sign Apk 然后出现下面的界面:

配置好基本信息以后,点击next,勾选V1、V2等一些配置即可完成签名打包。

第二种:在Android Studio 底部Tab的 Terminal窗口 输入 gradle a 命令(本质就是dos操作),来帮助我们打包

以上两种打包方式都是传统的打包方式,那么有没有更简单的操作?这种简单的操作类似我 在PC上面点击一个快捷方式就给我生成apk包?答案在开头已经说了是有的。

  1. 首先,我们在项目根目录下创建一个指定的文件夹(用于编译跑脚本用),这个文件一般定义为 .config文件(记住:前面有个 . )

  2. 然后,在这个文件夹内创建 build.bat文件。可能你会问什么是bat文件?bat文件是dos下的批处理文件。批处理文件是无格式的文本文件,它包含一条或多条命令。当我们双击bat文件的时候,系统就会调用cmd.exe按照该文件中各个命令出现的顺序来逐个运行它们。所以,我们只需要在这个bat文件里面写下相应的命令进行操作即可

  3. 既然现在我们需要在bat文件里面写命令,那么gradle里面有那些可以执行的打包命令?下面是收集到的一些资料,命令如下:

编译所有productFlavor及对应所有buildType的apk:

  • gradle assemble  //仅仅执行项目打包所必须的任务集

  • gradle build          //执行项目打包所必须的任务集,以及执行自动化测试,所以会较慢

如果当前Project包含多个Module,在Project根目录执行gradle assemble会编译所有的Module。

编译指定productFlavor及buildType的apk

gradle assemble[productFlavor][buildType]  //如果缺失某参数,则会把该参数的所有配置都进行编译,即如果运行gradle assembleflavor,则会编译出flavor所有buildType的apk。例如:

  • gradleassemble

  • gradle assembleflavorRelease

  • gradle assembleflavorDebug

注意:gradle支持命令缩写,上面两个命令也可以写成如下格式

  • $gradle a

  • $gradle ass

  • $gradle aR

  • $gradle assflavorR

  • $gradle aD

  • $gradle assflavorD

既然dos命令确定了,我们就可以写bat文件进行测试了:

接下来我们就可以将这个build.bat文件,设置为桌面快捷方式,然后双击,双击以后会弹出cmd窗口进行打包然后去指定的文件夹拿到apk即可。

以上步骤的前提是你需要配置好Gradle运行环境、熟悉Gradle的基本命令以及必要的耐心和不怕失败反复尝试的勇气。

总结

既然通过这种方式可以完成快速打包,那我们也可以通过Java的Swing首先写个窗口,然后通过点击去调用相应的bat文件进行后续的操作,也就是一个迷你的小型打包工具(产品和运营可能会觉得,这个工具好厉害哟,那你兼项去做ios吧)。当然也有一些开发人员将这种打包方式集成在别的工具上面。文章中使用的源码地址如下所示:

https://github.com/zuowutan/ShareAutoPack

Android 系统(198)---Android解放双手之Gradle自动化打包实战相关推荐

  1. Android之Gradle自动化打包实战

    前言: 解放双手,双击桌面快捷方式生成apk包,基于Gradle.bat文件让开发人员告别打包烦扰! 前不久有一个Unity3D研发的小仙女在羽毛球场问我关于Android Studio打apk的一些 ...

  2. Android系统架构-[Android取经之路]

    摘要:本节主要来讲解Android的系统架构 阅读本文大约需要花费10分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Android的平台设计,欢迎关注我,谢谢! 欢 ...

  3. android 服务端技术,移动应用服务器端开发(基于JSP技术)-2017 Android系统构架 Android系统构架.docx...

    Android系统构架 PAGE 1 目 录 TOC \o "1-3" \h \z \u 一.Android系统构架 1 二.Linux内核层 2 三.系统运行库层 3 (一)系统 ...

  4. 【android系统】android系统升级流程分析(二)---update升级包分析

    接下来我们将通过几篇文章来分析update.zip包在具体Android系统升级的过程,来理解Android系统中Recovery模式服务的工作原理.今天让我先来分析下升级包update.zip. 一 ...

  5. 【android系统】android系统升级流程分析(一)---recovery模式中进行update包升级流程分析

    今天我们直接来看下android中具体的升级过程是如何的. 升级流程概述 升级的流程图: 升级流程分析 第一步:升级包获取 升级获取可以通过远程下载,也可直接拷贝到指定目录即可. 第二步:准备升级 然 ...

  6. android log抓取方法,Android系统之Android抓取各种log的方法

    Android系统之Android抓取各种log的方法 2018年11月25日 | 萬仟网移动技术 | 我要评论 android之android抓取各种log的方法 1.logcat (四类log b ...

  7. Android 系统(223)---Android-打包与快速打包

    Android-打包与快速打包 前言 我们每一个产品中一般都是由一位同事来负责打包工作的,其他同学一般是不需要关心具体的流程的.然而掌握打包的知识对我们每一个人都是必要的,以备不时之需. 一般打包有两 ...

  8. android系统语音合成,android 语音合成报错

    发现了2个问题 第一个貌似是复制离线的资源出错了(已经核对过读写等权限): 12-19 19:54:49.739 32006-32159/com.zhanglf.youxuanz I/NonBlock ...

  9. Android 系统(71)---Android系统build.prop文件生成过程

    Android系统build.prop文件生成过程 Android系统build.prop生成过程 这个文件类似于windows的注册表文件,定义了系统初始的一些参数属性,功能的开放等,通过调整或增加 ...

最新文章

  1. 在PyTorch上用Keras,分布式训练开箱即用,告别没完没了的Debug
  2. Java编程思想 学习笔记7
  3. Android启动外部程序
  4. sklearn自学指南(part43)--数据加载工具
  5. android变量要不要附空值,android-如何在使用Parcelable时序列化空值
  6. stdint.h 文件
  7. vba校对不同工作薄中的内容
  8. android实现截图功能吗,Android实现拍照截图功能
  9. python爬虫怎么写多线程_Python爬虫【第3篇】【多线程】
  10. 微信可直接转账到 QQ;小米联合中国联通推出当前最便宜 5G 套餐;Git 2.25.0 发布 | 极客头条...
  11. 循环取矩阵的某行_一文搞懂RNN(循环神经网络)基础篇
  12. 阐述Spring框架中Bean的生命周期?
  13. Linux chapter 7
  14. kswapd进程与swap、swappiness之间的关系及原理
  15. 物业费管理java_java毕业设计_springboot框架的物业收费管理系统
  16. 【iOS开发】—— 调用相机、相册
  17. 特征点匹配——SIFT算法详解
  18. 【20211207】【雷达】毫米波雷达(一)—— 基本原理
  19. 无法打开csproj,因为此版本的应用程序不支持其项目类型 csproj
  20. 归并排序详解(Acwing 归并排序y总模板)

热门文章

  1. RTMP流媒体播放过程
  2. 基础IO(文件接口、安装内核源码超详细步骤图解、静态库与动态库)
  3. linux该专接本还是工作_2020河北专接本报考录取比例相差最大专业TOP榜,出乎意料吗?...
  4. netstat查看占用端口
  5. [K8S]kubeadm国内镜像安装方式
  6. 7 SDImageCache
  7. Long Shadows Generate是一款在线使用纯CSS3实现长阴影的效果,一款强大的扁平化长投影制造器。...
  8. Java的位运算符具体解释实例——与(amp;)、非(~)、或(|)、异或(^)
  9. 伪静态 apache重写
  10. SQL里变量的声明以及常用函数举例