Android hot fix 原理及测试用例设计
Posted 搜狗测试
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android hot fix 原理及测试用例设计相关的知识,希望对你有一定的参考价值。
一、背景
当一个App发布之后,突然发现一个严重bug,需要紧急修复,按照之前正常开发流程:重新打包App、测试、替换各个应用市场、渠道包、提示用户升级、用户下载、覆盖安装。这样,大大增加开发成本、影响到产品的口碑、造成用户流失。有没有办法以补丁的方式动态修复紧急Bug,不再需要重新发布App,不再需要用户重新下载,覆盖安装?
于是乎,涌现出来很多热补丁方案,能够让应用能够在无需重新安装的情况实现更新,帮助应用快速建立动态修复能力。
图1 app正常开发流程和热修复开发流程
二、业界的热修复技术方案、原理
native hook方案
是一种运行时在Native修改Filed指针的方式,使用dalvik_replaceMethod替换 class 中方法的实现实现方法的替换,达到即时生效无需重启,对应用无性能消耗的目的。主要方案:AndFix和Dexposed。
multidex方案
android程序启动的时候,ClassLoader 会按顺序遍历文件(Elements列表),然后从当前遍历的dex文件中找到相关java类来执行。基于这个原理,可以把需要替换的类打包到一个dex(patch.dex)中去,然后把这个dex插入到Elements的最前面(nuwa),或者差量的方式给出patch.dex,然后将patch.dex与应用的classes.dex合并,然后整体替换掉旧的dex(Tinker)。
图2 业界hot fix 技术方案
三、Apk文件结构
应用是用Java编写的,利用AndroidSDK编译代码,并且把所有的数据和资源文件打包成一个APK (Android Package)文件,这是一个后缀名为.apk的压缩文件,APK文件中包含了一个Android应用程序的所有内容,是Android平台用于安装应用程序的文件。APK就是一个zip压缩包,解开这个APK包我们可以看到以下的结构:
图3-1 apk文件结构
图3-2 apk文件结构
1) assets目录:
用于存放需要打包到APK中的静态文件,assets目录支持任意深度的子目录,用户可以根据自己的需求任意部署文件夹架构,而且res目录下的文件会在.R文件中生成对应的资源ID,assets不会自动生成对应的ID,访问的时候需要AssetManager类。
2) lib目录:
存放应用程序依赖的native库文件,一般是用C/C++编写。根据CPU型号的不同,这里lib库可能包含4种不同类型:ARM、ARM-v7a、MIPS、X86(分别对应ARM、ARM-V7、MIPS、X86架构)。这些so库在APK包中的构成如下:
图4 lib目录结构
3) res目录:
res是resource的缩写,这个目录存放资源文件,存在在这个文件夹下的所有文件都会映射到Android工程的.R文件中,生成对应的ID,访问的时候直接使用资源ID即R.id.filename。res文件夹下可以包含多个文件夹,anim存放动画文件、drawable存放图像资源、layout存放布局文件、values存放一些特征值、colors.xml存放color颜色值、dimens.xml定义尺寸值,string.xml定义字符串的值、styles.xml定义样式对象、xml文件夹存放任意xml文件(运行时可以通过Resources.getXML()读取)。
4) META-INF目录:
保存应用的签名信息,验证APK文件的完整性。AndroidSDK在打包APK时会计算APK包中所有文件的完整性,并且把这些完整性保存到META-INF文件夹下,应用程序在安装的时候首先会根据META-INF文件夹校验APK的完整性,保证APK中的每一个文件都不能被篡改,确保APK应用程序不被恶意修改或者病毒感染,有利于确保Android应用的完整性和系统的安全性。
5) AndroidManifest.xml:
Android应用程序的配置文件,是一个用来描述Android应用“整体信息”的设定文件,相当于Android应用向Android系统“自我介绍”的配置文件,Android系统可以根据这个“自我介绍”完整地了解APK应用程序的资讯,每个Android应用程序都必须包含一个AndroidManifest.xml文件,且它的名字是固定的,不能修改。程序打包时,会把AndroidManifest.xml进行简单的编译,便于Android系统识别,编译之后的格式是AXML格式,如下图所示:
图5 AXML格式
6) classes.dex:
传统的Java程序,首先把Java文件编译成class文件,字节码都保存在了class文件中,Java虚拟机解释执行这些class文件。
Dalvik虚拟机在Java虚拟机进行了优化,执行的是Dalvik字节码,这些Dalvik字节码是由Java字节码转换而来。
一般Android应用在打包时通过AndroidSDK中的dx工具将Java字节码转换为Dalvik字节码。dx工具可以对多个class文件进行合并,重组,优化,可以达到减小体积,缩短运行时间的目的。dx工具的转换过程如图所示:
图6 工具把.class文件转换成dex文件
dx工具把每个.class文件的每个区域的内容进行去重,重组,优化重排后生成dex文件,生成的dex文件可以在Dalvik虚拟机执行,且速度比较快。
7) resources.arsc:
用来记录资源文件和资源ID之间的映射关系,根据资源ID寻找对应资源。Android的开发是分模块的,res目录专门用来存放资源文件,当在代码中需要调用资源文件时,只需要调用findviewbyId()就可以得到资源文件,每当在res文件夹下放一个文件,aapt就会自动生成对应的ID保存在.R文件,调用这个ID就可以。.R文件只是保证编译程序不报错,实际在程序运行时,系统要根据ID去寻找对应的资源路径,resources.arsc文件就是用来记录这些ID和资源文件位置对应关系的文件。
四、APK安装过程
Adroid应用安装涉及到如下几个目录:
/data/app:存放用户安装的APK的目录,安装时,把APK拷贝于此。
/data/data:应用安装完成后,在/data/data目录下自动生成和APK包名(packagename)一样的文件夹,用于存放应用程序的数据。
/data/dalvik-cache:存放APK的odex文件,便于应用启动时直接执行。
具体安装过程如下:
首先,复制APK安装包到/data/app下,然后校验APK的签名是否正确,检查APK的结构是否正常,进而解压并且校验APK中的dex文件,确定dex文件没有被损坏后,再把dex优化成odex,使得应用程序启动时间加快,同时在/data/data目录下建立于APK包名相同的文件夹,如果APK中有lib库,系统会判断这些so库的名字,查看是否以lib开头,是否以.so结尾,再根据CPU的架构解压对应的so库到/data/data/packagename/lib下。
APK安装的时候会把DEX文件解压并且优化位odex,odex的格式如下图所示:
图7 odex文件格式
odex在原来的dex文件头添加了一些数据,在文件尾部添加了程序运行时需要的依赖库和辅助数据,使得程序运行速度更快。
五、Tinker方案-热修复测试点
因素 |
测试重点 |
测试内容 |
性能损耗(运行) |
监测内存、cpu等性能指标 |
|
兼容性 |
机型兼容性测试,成功转化率 |
|
替换范围 |
几类替换类型,进行测试 |
|
性能损耗(安装) |
监测内存、cpu等性能指标,是否能成功安装,不被杀掉 |
|
补丁包大小 |
观察热修复内容同补丁包大小的比例关系 |
|
即时生效 |
重启应用生效/即时生效 |
|
稳定性 |
合并过程中,应用是否会有crash、ANR |
|
基本功能相关 |
本地检测补丁包机制、补丁包下载服务流程、补丁版本的相关信息; |
以上是关于Android hot fix 原理及测试用例设计的主要内容,如果未能解决你的问题,请参考以下文章