了解APK结构
![](https://img.haomeiwen.com/i8669504/36f7a4b12cfe3ed1.png)
-
classes.dex: 代码文件
传统的Java程序,首先先把Java文件编译成class文件,字节码都保存在了class文件中,Java虚拟机可以通过解释执行这些class文件。而Dalvik虚拟机是在Java虚拟机进行了优化,执行的是Dalvik字节码,而这些Dalvik字节码是由Java字节码转换而来,一般情况下,Android应用在打包时通过AndroidSDK中的dx工具将Java字节码转换为Dalvik字节码。
-
assets目录:
用于存放需要打包到APK中的静态文件,这些资源不会被编译成二进制。
-
lib目录:
这里存放应用程序依赖的native库文件。
-
res目录:
这个目录存放资源文件,直接将项目的res目录打包进来。
-
resources.arsc:
用来记录资源文件和资源ID之间的映射关系,用来根据资源ID寻找资源。包括stirng,id,anim,style,mipmap,dimen等类型。
-
META-INF:
AndroidSDK在打包APK时会计算APK包中所有文件的完整性,并且把这些完整性保存到META-INF文件夹下,应用程序在安装的时候首先会根据META-INF文件夹校验APK的完整性,这样就可以保证APK中的每一个文件都不能被篡改。META-INF目录下包含的文件有CERT.RSA,CERT.DSA,CERT.SF和MANIFEST.MF,其中CERT.RSA是开发者利用私钥对APK进行签名的签名文件,CERT.SF,MANIFEST.MF记录了文件中文件的SHA-1哈希值。
-
Androidmenifest.xml:
清单配置文件自不必说。
压缩Apk具体措施
-
使用混淆、启动资源缩减
在gradle使用minifyEnabled进行Proguard混淆的配置,可大大减小APP大小。shrinkResources移除未使用的资源。
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
-
删除无用资源
从Analyze——>Run Inspection by Name进入,输入unused resources。
![](https://img.haomeiwen.com/i8669504/d801ac4026ff4af1.png)
对整个项目或者某个模块进行未使用资源扫描。
可以看到扫描结果下,没用到的资源,会标明warning,可以选择单个删除还是统一删除。
![](https://img.haomeiwen.com/i8669504/90f5865ee900eb84.png)
-
动态库打包配置
如果项目中使用到so库,只需要打armeabi-v7a架构,就可以兼容绝大多数cpu类型,这样可以减少apk中lib大小。
-
使用体积更小图片——使用wepb、SVG、iconfont图片
使用Webp来代替JPG和PNG图片,它保留了JPG和PNG优点的同时,能提供更好的压缩,达到更小的体积。
WebP的优势在于它具有更优的图像数据压缩算法,在拥有肉眼无法识别差异的图像质量前提下,带来更小的图片体积,同时具备了无损和有损的压缩模式、Alpha 透明以及动画的特性,在 JPEG 和 PNG 上的转化效果都非常优秀、稳定和统一。会比转为png和jpg的图片小25%-35%。
你可以使用矢量图形来绘制分辨率无关图标及其他可伸缩媒体文件。整个屏幕那么大的清晰图片,如果使用矢量图可能只需要100-byte大小。
-
webp和png的区别
![](https://img.haomeiwen.com/i8669504/763a08d72c5f6330.png)
PNG 转 WebP 的压缩率要高于 PNG 原图压缩率,同样支持有损与无损压缩
转换后的 WebP 体积大幅减少,无损压缩后的 WebP 比 PNG文件少了 45% 的文件大小,图片质量也得到保障(同时肉眼几乎无法看出差异),
转换后的 WebP 支持 Alpha 透明和 24-bit 颜色数。
可见除了 WebP 在解码时间与 PNG 有较明显差异(毫秒级别)之外,总体使用体验和 PNG 基本无差异。
解码耗时:WebP 的解码时间是 PNG 格式的 4-5 倍(24.8ms)
流畅程度:两种格式下,AIO 滑动流畅度无明显差异
CPU使用:两种格式下,连续发送 15 个表情,CPU 使用均在 10%—26% 之间波动,两者无明显差异
内存占用:两者格式下,连续发送 15 个表情,PSS 内存占用跨度均为 11M,无明显差异
参考:
https://blog.csdn.net/Android_machong/article/details/53258924
-
减小classes.dex包大小
减少代码量,这个就需要看自己团队的实力了,搭建复用性更高的框架,选择更合理的开发模式来减少代码量,能不必要引入的库可以团队完成。
-
资源混淆
微信混淆方案(AndResGuard)是通过修改aapt在处理资源文件相关的源码达到资源文件的替换。它会将原本冗长的资源路径变短,例如将res/drawable/wechat变为r/d/a。
1.在项目根目录的gradle文件下加入资源混淆插件:
dependencies {
classpath 'com.tencent.mm:AndResGuard-gradle-plugin:1.2.10'
}
2.在app的gradle下加入配置:
plugins {
id 'AndResGuard'
}
andResGuard {
// mappingFile = file("./resource_mapping.txt")
mappingFile = null
use7zip = false
useSign = true
// It will keep the origin path of your resources when it's true
keepRoot = false
// If set, name column in arsc those need to proguard will be kept to this value
fixedResName = "arg"
// It will merge the duplicated resources, but don't rely on this feature too much.
// it's always better to remove duplicated resource from repo
mergeDuplicatedRes = true
whiteList = [
// your icon
"R.drawable.ic_launcher*",
"R.anim.umeng*",
"R.string.umeng*",
]
compressFilePattern = [
"*.png",
"*.jpg",
"*.jpeg",
"*.gif",
"*.webp",
]
sevenzip {
artifact = 'com.tencent.mm:SevenZip:1.2.20'
//path = "/usr/local/bin/7za"
}
}
whiteList(白名单)中指定不需要进行混淆的资源路径规则,主要是针对第三方SDK,因为有些SDK的代码中通过getIdentifier()的方式引用到对应的资源文件,如果对其进行混淆,会导致找不到对应资源文件,出现crash。
网友评论