目录
1.概述
- apk包的打包过程
- class到dex的变化过程中发生了什么?
- jvm、dvm和art的区别
- 如何打渠道包
- 如何减小包的大小
2.apk的打包过程
- 1)打包资源文件,生成R.java文件——aapt
- 2)处理aidl文件,生成对应Java文件——aidl
- 3)编译Java文件,生成对应的.class文件——javac
- 4)生成dex文件——dex
- 5)打包生成未签名的apk文件——apkbuilder
- 6)对apk进行签名——jarsinger
- 7)对签名后的apk进行对齐处理——zipalign工具(google market)
- 参考文献:https://cloud.tencent.com/developer/article/1392511
3.class到dex的变化过程中发生了什么?
3.1 过程/工具
Java文件经编译javac,生成了对应的class文件,jar包,使用de.jar工具可以实现从class文件到dex的转换。
3.2 对比
名称 | 定义 | 相同点 | 优点 | 缺点 |
class | 被jvm识别,加载成为可执行的机器指令,记录了类文件的所有信息 | 本质相同,都是二进制文件流格式,dex是由class发展而来 | 1.占用内存大——不适合移动端 2.堆栈的加载模式导致加载速度慢 3.文件IO操作多,类查找慢 | |
dex | 被dvm或者art虚拟机执行并加载,记录了整个工程的所有类文件信息(不分包的情况下) | class包含荣冗余信息,dex则去除了冗余信息,并整合整个工程的类信息。 |
3.3 Multi dex
为什么?
- 1)应用方法数超过65536,或者加上依赖的jar包等超过65536;
- 2)Android2.3以前的系统安装异常,dex文件优化程序中,dexopt有固定大小的缓冲区,来存储所有方法的信息,老版本的缓存区为5M,新版本为8-16M,在老版本中容易超过限制。
方法数越界的解决方案:
1)插件化技术,动态加载部分dex
2) multidex方案
加载过程?如何进行查找类的?
https://blog.csdn.net/lisdye2/article/details/80929663
将每一个.zip
转化为DexPathList.Element
,添加到DexPathList
的elements
字段中。这样在加载一个类的时候就会遍历所有的dex文件,保证了打包的类都能够正常加载。
分包的时候,由于加载和初始化的问题,如某个类不在主dex中,会出现找不到类的异常。=》解决方案:配置maindexlist.txt,列出需要在dex中的类。
4.jvm、dvm、art的比较
名称 | 定义 | 原理 | 特点 | 优点 | 缺点 | 备注 |
jvm | java虚拟机 | java文件编译为字节码-class文件,运行在jvm上,由jvm翻译成机器指令。 | 1.一个Java文件对应一个class文件,文件数量多;具有自己的常量池和数据区域; 2.基于栈结构——频繁从栈上读写数据,多次指令分配和内存访问 |
| 1.文件体积大; 2.栈机构,耗CPU; | 都提供了对象生命周期管理、堆栈管理、线程管理、安全和异常管理及垃圾回收等功能,格子布具有完整的指令系统。—jvm和dvm 应用程序的安装时机:1.系统启动时,2.用户自行安装时 |
DVM | Dalvik虚拟机 | 将class文件打包编译成dex文件,运行的是Dalvik字节码,每一个进程对应一个虚拟机。 | 1.所有的文件对应一个dex或者多个(multi dex),文件数量少;共享一个常量池; 2.基于寄存器结构——比栈快速 | 可运行文件体积比jvm的更小——dx工具对Java类文件进行了排列,将全部Java类文件中的常量池分解,消除冗余信息。共享一个常量池。 | 1.文件体积小; 2.耗时少;运行速度快。 |
|
ART vm | Art运行时虚拟机 | Android4.4出现,运行的是本地机器码,基于JIT(just in time即时编译技术)和AOT(Ahead of time预编译技术) | 1.打包好的应用程序仍然是包含dex的apk文件; 2.安装时,dex被编译成本地机器码,之后每次运行都是本地机器码,移除了运行时的解释运行-—以空间换取时间 | 1.系统性能显著提升; 2.应用启动更快、运行更快、体验更流畅、触感反馈更及时; 3.续航能力提升; 4.支持更低的硬件 | 1.更大的存储空间占用,可能增加10%-20%; 2.更长的应用安装时间。
| jit——javac把程序源代码编译成Java字节码,jvm进行逐条翻译成机器指令。运行速度慢。在运行时分析代码,识别出热方法,被jit编译器编译成汇编代码,存储在代码缓存中,供调用时直接使用; AOT——编译器直接将源代码编译成目标机器码,运行时可直接运行。 |
5.如何打渠道包?有什么优缺点?
5.1 基本概念
打包:根据签名和其他标识生成安装包
签名:Android应用文件中保存的一个特殊的字符串,用来标识不同的开发者,一个应用开发者开发的多款应用应使用同一个签名。
为什么要签名?
1)系统要求,经过签名才能安装;
2)应用包名可能相同,导致应用被覆盖,签名不一致才会进行覆盖;
怎么签名?——略。
多渠道包:
在安装包中添加渠道信息,即channel
为什么?便于运营统计
原理:AndroidManifest.xml中的Application的Metadata中,可以通过api获得对应的数据
5.2 如何实现?
1)友盟提供的方式,配置gradle。缺点:打包效率低,几十个还可以。
2)美团提供的方式,把apk当做zip包进行解压,在Meta-Inf目录下添加一个空文件,不需要重新签名。优点:打包快,缺点,新的签名规则可能不适用。存在网络劫持和篡改渠道的可能性
3)360提供的方式,优点:打包快,下载apk的同事。服务端可以写入信息,缺点:存在渠道信息被修改的风险
怎么解决被可能被修改的问题?
6.如何减小包的大小
减包——减小包体积
1.减少资源
1)减少资源个数和尺寸,使用可缩放的drawable对象代替图片文件
2)移除不再使用的资源,使用lint查找;
3)调整gradle配置,如resConfigs和defaultConfig的值;
4)最小化第三方库中的资源使用;
5)只支持部分屏幕密度,不需要为每个密度都配置资源,按照用户占比,xxhdpi
6)减少动画帧数;
7)使用Drawable动态绘制图像,xml文件占用控件少,能产生遵循Material Design设计规范的图像;
8)重用资源
9)绘制图片
10)压缩图片
11)使用webp文件格式,有损压缩
2.减少native和Java代码
1)减少不必要的代码生成;
2)移除枚举,使用intDef和Proguard代替
3)较少native库的大小,优化代码,删除调试符号和避免抽取native库