gradle打包android
A. [Unity] 使用Gradle系统打包
新版本的Unity中,提供了新的Build System —— Gradle。
使用Gradle打包前,首先要创建keystore,配置好签名才能使用。具体步骤如下:
1.打开Files -> Build Settings -> Player Settings ->Publishing Settings,看到keystore配置。
2.在Create a new keystore 的单选框里打上√,在下面的输入框中输入密码。(记住这个密码,打包的时候需要输入哦!)
3.点击Browse Keystore按钮,填写名字后保存。
保存后,会在按钮旁显示路径。
4.点击 Alias 下拉框,选择Create a new key,这时候会跳出一个弹窗,填写信息后创建一个key。这时候就能在 Alias 下拉框中选到你创建的key,然后输入创建key时的密码。
5.选择 Build System 为 Gradle,并在Custom Gradle Template 单选框中打√。
6.上图中的mainTemplate.gradle需要从Unity中复制出来导入项目,并进行相关配置,文件地址在:Unity安装位置Unity -> Editor -> Data -> PlaybackEngines -> AndroidPlayer -> Tools -> GradleTemplates
这时候就可以进行Build或者Export了。
还有一些地方值得注意的是,Unity的Gradle tools工具的版本,以及Android Studio的Plugins版本以及Gradle版本,要对应,不然会报错。
Unity使用的Gradle Tools版本:打开mainTemplate.gradle文件可以看到一下信息,如果有使用其他arr包建议使用一样的gradle版本。
Unity使用的Gradle Plugin版本:项目地址 -> Temo -> gradleOut -> .gradle
Android Stuido中的版本:File -> Project Structure -> Project
他们之间的对应关系如下图,参考链接: https://developer.android.com/studio/releases/gradle-plugin#updating-gradle
B. Android Studio 工具的使用介绍、项目结构,打包、gradle、调试
刚开始使用,看到这么多东西是不是很方?别怕,慢慢来(笑)
File :新建、打开项目!
Preferences :设置
Edit :主要包括复制粘贴、Find查找
Build :构建项目,构建单个moudle、clean项目、build apk 构建一个没有签名的APK
Build Generate Singed Apk 构建一个有签名的APK,和Ecplise一样如果有现成的签名文件可 以直接导入使用,如果没有 可以创建一个。.jks和.keystore都是app签名文件使用没区别。
Run :主要包括运行app 或者Debug运行app
VCS :版本控制包含了git github svn vcs等导入导出项目到版本控制服务器
Android工程是通过gradle文件管理各项配置哒,分成两个层级: project 和 mole
build.gradle
Mole层级的build.gradle的主要用于配置Mole的,下面看看它的一些配置
让它运行一下:
这个时候就可以在下面看到当前运行情况
C. 新一代Android渠道打包工具:1000个渠道包只需要5秒
♥♥♥ 原文转自 极分享 更多详情及更新 查看原文 ♥♥♥
最新版本
v1.0.4 - 2016.01.19 - 完善获取APK路径的方法,增加MarketInfo
v1.0.3 - 2016.01.14 - 增加缓存,新增ResUtils,更有好的错误提示
v1.0.2 - 2015.12.04 - 兼容proctFlavors,完善异常处理
v1.0.1 - 2015.12.01 - 如果没有读取到渠道,默认返回空字符串
v1.0.0 - 2015.11.30 - 增加java和python打包脚本,增加文档
v0.9.9 - 2015.11.26 - 测试版发布,支持全新的极速打包方式
源码:https://github.com/mcxiaoke/packer-ng-plugin
项目介绍
packer-ng-plugin 是下一代Android渠道打包工具Gradle插件,支持极速打包,1000个渠道包只需要5秒钟,速度是 gradle-packer-plugin 的1000倍以上,可方便的用于CI系统集成,支持自定义输出目录和最终APK文件名,依赖包:com.mcxiaoke.gradle:packer-ng:1.0.+ 简短名:packer,可以在项目的 build.gradle 中指定使用,还提供了命令行独立使用的Java和Python脚本。实现原理见本文末尾。
使用指南
Maven Central
.
.
.
.
.
实现原理
PackerNg原理
优点
使用APK注释字段保存渠道信息和MAGIC字节,从文件末尾读取渠道信息,速度快
实现为一个Gradle Plugin,支持定制输出APK的文件名等信息,方便CI集成
提供Java版和Python的独立命令行脚本,不依赖Gradle插件,支持独立使用
由于打包速度极快,单个包只需要5毫秒左右,可用于网站后台动态生成渠道包
缺点
没有使用Android的proctFlavors,无法利用flavors条件编译的功能
文件格式
Android应用使用的APK文件就是一个带签名信息的ZIP文件,根据 ZIP文件格式规范,每个ZIP文件的最后都必须有一个叫Central Directory Record 的部分,这个CDR的最后部分叫"end of central directory record",这一部分包含一些元数据,它的末尾是ZIP文件的注释。注释包含Comment Length和File Comment两个字段,前者表示注释内容的长度,后者是注释的内容,正确修改这一部分不会对ZIP文件造成破坏,利用这个字段,我们可以添加一些自定义的数据,PackerNg项目就是在这里添加和读取渠道信息。
细节处理
原理很简单,就是将渠道信息存放在APK文件的注释字段中,但是实现起来遇到不少坑,测试了好多次。
同类工具
gradle-packer-plugin - 旧版渠道打包工具,完全使用Gradle系统实现,能利用Android提供的proctFlavors系统的条件编译功能,无任何兼容性问题,方便集成,但是由于每次都要重新打包,速度比较慢,不适合需要大量打包的情况。(性能:200个渠道包需要一到两小时)
Meituan-MultiChannelTool - 使用美团方案的实现,在APK文件的META-INF目里增加渠道文件,打包速度也非常快,但读取时需要遍历APK文件的数据项,比较慢,而且以后可能遇到兼容性问题
MultiChannelPackageTool - 将渠道写入APK文件的注释,这个项目没有提供Gradle插件,只有命令行工具,不方便CI集成,使用ZIP文件注释的思路就是来自此项目
转自 极分享 阅读原文
D. Android简单的打包配置
在android studio中的打包,通常使用以下两个选项之一,两个方式都可以构建出apk包
这两个有什么区别?
概括一句话:根据gradle中现有的签名配置进行自动签名打包
通常debug和dev环境是系统自行配置的debug-sing签名,不需要手动进行配置,但是release环境是对外发布的环境,必须要求手动在gradle中进行签名配置才可以打包(后边说)
所以在gradle配置好了签名的情况下,直接点击 Build APK(s) 就可以进行打包
一句话概括:通过手动选择签名文件进行签名打包
这种方式则不需要在gradle中进行配置,直接选择你已经创建好的签名文件,输入对应的密码等信息,就可以进行打包
然后就可以进行打包了
debug 和 dev 等测试/开发环境 因为系统自动配置了debug-sing 可以直接使用 Build APK(s) 进行打包。
但是release环境需要对外发布,所以需要手动在gradle中进行签名配置才可以使用 Build APK(s) ,或着自己选择 Generate Signed Bundle or APK 通过签名文件进行打包(效果和gradle中配置好了签名文件完全相同)
那么就有以下两个问题:
在 Generate Signed Bundle or APK 中选择 Create new ...
在mole的gradle.android中输入:
然后在配置环境的buildTypes中,想使用 signingConfigs 签名配置的环境加上一句话: signingConfig signingConfigs.release
这样,就在gradle中配置好了签名,可以直接使用 Build APK(s) 进行打包
注意这里的 minifyEnabled true 也就是要使用混淆文件(一般测试环境为false 编译更快)。如果release环境打包,没有配置好混淆文件的话,会导致apk安装之后,秒退。(如果没有签名强行打包,则无法安装)
E. Android 打包流程
打包后的apk是一个压缩包,解压之后,内容如下:
详细可参考 apk签名原理
无论我们怎么配置gradle文件去自定义打包,但是都是要走上图所画的七个流程。七个深绿色的椭圆代表了七个不可或缺的打包步骤,并且每一个步骤都一个打包工具
所用到的工具:
zipalign 字节对齐:
为什么要以4字节整数倍为起始偏移?
在文件对齐后, 就可以使用mmap来直接读写apk文件
mmap映射
上面涉及到的Android打包流程是以gradle task链的形式串联起来的。
下面看一下常见的task
件
我可以想到的:
Transform API
https://www.jianshu.com/p/a134d00e81ab
https://www.jianshu.com/p/fffb81688dc5
F. Android gradle 打包错误A problem occurred configuring project ':app'.
因为项目为插件工程,每次编译需要使用“./gradlew pushPlugin”自动push到壳工程,但是...我的不行,就不行...
错误如下:
一脸懵逼,完全看不懂....
按照提示尝试找找错误原因,然后一顿操作,猛如虎:
./gradlew --stacktrace
./gradlew --info
./gradlew --scan
...
这个错误感觉有点意思,可能是病灶的根源,仔细一看,确实,经过几分钟仔细研究,终于知道了:
解决方案:
1、我首先去把as的jre配置地方改成系统的,发现,改不了,放弃...
2.as不让改,还不能改自己的么,改本地的环境变量,把java_home的jre换成as的jre地址,
结果,编译的特别丝滑...
问题解决了,但是总觉得怪怪了,因为本地jre环境被改了,不舒服,哈哈,原因很简单啊,本地jdk以后升级就不行了,第二种方法只是暂时解决了,并不完美,所以还得再想想...
终极解决:
编写了一个脚本文件,主要作用有俩个,第一是临时替换本地jre的地址,指向到as的。第二是直接编译,然后push;
脚本如下:
ps:把地址换成自己as的jre地址就可以,注意分隔符的方向
运行编译,完美编译, 丝滑 ...
G. Android Studio中gradle命令指定打jar包...
近期在项目中需要对网络访问接口进行jar封装。
在eclipse中进行指定类进行打jar包很简单,但是在android studio中则有点困难,其主要的原因是需要掌握gradle命令形式。接下来就直接上干货。
首先,在你需要进行分装jar的模块进行build.gradle文件下进行以下添加:
然后在Windos CMD中跳转到你的项目路径下,然后执行gradle makeJar命令,如果提示:gradle命令不可用。那么你需要在你的系统环境变量中进行变量的添加:
找到你的gradle插件路径进行添加,然后再在path属性的末尾进行
“;%GRADLE_HOME%\bin”添加。
然后输入 "gradle -v"或者"gradle -version"都可以.
如图就说明gradle配置成功了。
然后再cmd命令到你的项目路径下,然后再次输入gradle makeJar回车,
这里提示我们在我需要进行jar分装的模块出错了, 我们按照错误提示进行修改 ,在buold.gradle文件中添加
lintOptions {
abortOnErrorfalse
}
然后点击Sync Now。再次运行gradle makeJar。然后再一长串的编译后在末尾看到
然后我们在项目模块的build/libs文件夹下看到了我们命名的.jar文件
OK,到此就结束了。上面是个简单的例子,只能打包某个包下面的所有文件,如果要实现只打某个包下面的某些子包或者文件可参考如下示例:
taskmakeSdkJar(type:org.gradle.api.tasks.bundling.Jar){
baseName'pluginsdk'
//只打包org.cmdmac下的org.cmdmac.pluginsdk.impl和org.cmdmac.gamecenter,其他子包不会被打包进去
from('build/intermediates/classes/debug/org/cmdmac/'){
include'pluginsdk/impl'
include'gamecenter'
}
into('org/cmdmac/')
// exclude('R.class')
// exclude{ it.name.startsWith('R$');}
taskmakeSdkJar(type:org.gradle.api.tasks.bundling.Jar){
baseName'pluginsdk'
//只打包org.cmdmac下的org.cmdmac.pluginsdk.impl和org.cmdmac.gamecenter,其他子包不会被打包进去
from('build/intermediates/classes/debug/org/cmdmac/'){
include'pluginsdk/impl'
include'gamecenter'
}
into('org/cmdmac/')
// exclude('R.class')
// exclude{ it.name.startsWith('R$');}
}
H. Unity3D使用gradle打Android包遇到的aaptOptions.noCompress越界问题及解决方案
Unity3D使用gradle方式打Android包,如果StreamingAssets下文件较多,会打包失败,错误如下:
java.lang.: 1866
at org.codehaus.groovy.classgen.asm.CallSiteWriter.getCreateArraySignature(CallSiteWriter.java:58)
原因是aaptOptions.noCompress数组越界,对此问题的详细描述参考博文:
Unity导出Gradle工程或者apk包,StreamAssets目录文件超过255无法导出的问题 ... ... ... - liqing19850102的专栏 - CSDN博客
aaptOptions.noCompress数组的最大容量为255,也即可以不经压缩打到apk包里的资源文件数不能超过255个。
原文中提供的解决方案是,把Unity默认的配置中的 **STREAMING_ASSETS** (含义为StreamingAssets文件夹下所有资源都不压缩)去掉,改为只针对某些类型的资源不压缩,比如.bundle
这里我想在原文基础上拓展三点,来深化对这一问题的认识。
一,为什么要配置aaptOptions.noCompress
简单来说,可以提升资源加载效率,因为加载压缩过的资源需要一个解压过程
那么哪些资源需要配置到aaptOptions.noCompress呢?
我们来看一下Unity的默认配置,
aaptOptions { noCompress'.unity3d','.ress','.resource','.obb'**STREAMING_ASSETS** }
.resource是Resources目录下资源编译后生成的文件
**STREAMING_ASSETS** 代表StreamingAssets文件夹下的文件
可见动态加载的资源一般要配置到aaptOptions.noCompress里,以提升加载效率
二,当使用默认配置超出最大容量255时怎么办
两种思路
a,将一些小的使用不频繁的文件从列表中移出
b,将多个文件合并为一个(比如打成bundle)来减少列表中文件数量
这里有必要解答一个疑问,经常会遇到StreamingAssets下文件数量远小于255,但打包还是会报错,这是为什么呢?其实是Resources目录下资源太多,所以生成的.resource文件数量较多导致的,这种情况下好的解决方案就是将Resources下一些资源打成bundle来使用,减少.resource文件的数量
三,aaptOptions.noCompress配置技巧
aapt官方文档以及网上查到的一些资料都说aaptOptions.noCompress配置的是不压缩资源文件的后缀名,但是使用后缀名来配置有一定的局限性,比如有些文件后缀名相同,但是如果只想将其中几个文件(而不是全部)配成不压缩,再比如有的文件没有后缀名怎么办?
经过实践发现aaptOptions.noCompress机制并不是检查文件后缀名,而是判断文件路径是否以某个字符串结尾,另外一个需要注意的地方是,在做string.EndWith判断之前会将文件路径全部转换为小写,所以aaptOptions.noCompress中的配置项也必须全为小写
I. Jenkins+Gradle+Github实现Android自动化打包
利用Jenkins搭建Android自动化打包。
参考 Jenkins+Git配置 和 Android使用Jenkins持续集成 进行整理。
选择对应系统的稳定版本,这里装的是Mac版本。
可以选择在步骤1安装过程中选择默认的插件安装,也可以在主页 系统管理 中选择 插件管理 进行安装。
配置打包类型,这里的参数对应的是Android项目gradle配置里面的 buildTypes 设置的打包类型。
点击 Git Parameter (如果没有这个参数检查一下对应的插件是否安装)
在GitHub上找到 setting
在项目下的 settings 点击进去
先检查插件 Gitlab Hook Plugin 是否安装
点击 系统管理 -> 系统设置 -> GitHub -> 添加GitHub服务器
自此已配置完成,我们开始来点击构建项目。项目下面点击 Build with Parameters ,可以看到我们之前设置的配置。打包类型和分支选择。
J. ANDROID多渠道快速打包实践
参考资料:
美团Android自动化之旅—生成渠道包
Android批量打包提速
AndroidMultiChannelBuildTool
背景
随着发版需要,每次发版所需渠道包越来越多(现在差不多有一百个左右了),正常gradle打包由于耗时效率过低已无法满足需求,开始了android多渠道快速打包实践。
方法
下面主要介绍两种快速打包的方式:
1、类似美团的方式,在META-INF中写入渠道名的空文件,用于读取空文件。 美团Android自动化之旅—生成渠道包
2、在apk末尾动态写入渠道信息。 一种动态为apk写入信息的方案
其实这两种方式都是同一个原理,替换以前从manifest中读取渠道号的方式,而使用新的获取方式(渠道号如何写入就如何读取)。
所以这首先需要客户端(重要!):
1、统一应用中获取渠道的方式并替换之前的(最好兼容)。
2、注意第三方SDK渠道号的传入,比如友盟sdk,否则第三方会使用默认从manifest中读取的方式。
下面介绍一种已经测试过的方法(git上开源项目 AndroidMultiChannelBuildTool )
1、安装环境由于脚本环境是使用python语言,所以需要我们 安装环境 。
2、导入项目导入开源项目 AndroidMultiChannelBuildTool ),并把想要批量打包的apk文件拷贝到PythonTool目录下(与py同级),运行py脚本即可打包完成。
以上基本实现快速打包,经过测试一分钟百十个无压力。另外需要注意这种方式只适用于打包需求一致渠道号不同,不适用特殊定制渠道。
备注:9月21日补充快速打包java版本,详见 AndroidMultiChannelBuildTool-Java-master