1,APK的组成
APK文件就是一个Zip格式的文件,其中包含构成应用的所有文件,这些文件包括Java类文件、资源文件和包含已编译的文件
APK包含一下目录
META-INF:包含CERT.SF和CERT.RSA签名文件,以及MANIFEST.MF清单文件
assets/:包含应用的资源;应用可以使用AssetManager对象检索这些资源
res/:包含未编译到resources.arsc中的资源(图片、音视频等)
lib/:包含特定于处理器软件层的已编译代码,此目录包含每种平台类型的子目录,如armeabi、armeabi-v7a、arm64-v8a、x86、x86_64和mips。
APK还包含一下文件,在这些文件中,只有AndroidManifest.xml是必须的
resources.arsc:包含已编译的资源,此文件包含res/values/文件夹的所以配置中的xml内容,打包工具会提取此xml内容,将其编译为二进制文件形式,并压缩内容,此内容包括语言字符串和样式,以及未直接包含在resource.arsc文件中的内容(例如布局文件和图片),此内容语言字符串和样式,以及未直接包含在resources.arsc文件中的内容(例如布局文件和图片)的路径
Classes.dex: 包含以Dalvik/ART虚拟机可理解的DEX文件格式编译的类
AndroidManifest.xml:包含核心Android清单文件,此文件列出了应用的名称、版本、访问权限和引用的库文件,该文件使用Android的二进制XML格式
2,Android Size Analyzer
从菜单栏中一次选择Analyze>Analyze App Size,对当前项目运行应用大小分析,分析了项目后,系统会显示一个工具窗口,其中包含有关如何缩减应用大小的建议
3,启用资源缩减
如果在应用的build.gradle文件中启用了资源缩减: shrinkResources,则Gradle在打包APK时可以自动忽略未使用资源,资源缩减只有与代码缩减,minifyEnabled配合缩减器移除所以不使用的代码后,资源缩减其便可确定应用仍要使用的资源,从而在打包时优化这些资源
Android {
BuildTypes{
Release {
MinffyEnabled true
ShrinkResources true
ProguardFiles getDefaultProguardFile(‘proguard-android.txt’), ‘proguard-reles.pro’
}
}
}
4,使用Link分析器
Lint工具是android studio中附带的静态代码分析器,可检测到res/文件中未被代码引用的资源,lint工具不会扫描assets/文件夹、通过反射引用的资源或已连接至应用的库文件,此外,它也不会移除资源,只会提醒有未使用的资源
从菜单栏中一次选择analyze > Run Inspection By Name > 输入“unused resources”回车执行
5,自定义要保留的资源
如果有想要特别声明需要保留或舍弃的特定资源,创建res/raw/keep.xml, tools:keep属性中指定每个要保留的资源,在tools:discard属性中指定每个要舍弃的资源,这两个属性都接受以都好分割的资源名称列表,还可以将星号字符用作通配符
<?xml version=”1.0” encoding= “utf-8” ?>
<resources xmlns: tools = “http://schemas.android.com/tools”
Tools:keep= “@layout/1_used*_c, @layout/1_used_a, @layout/1_used_b”
Tools:discard = “@layout/unused2”/>
6,移除未使用的备用资源
一般开发我们都会引入各种依赖,这些依赖可能包含各种备用资源,如中文,英文、日韩文等等。如果我们不需要这些语言可以让他们不打包进入Apk android { .... resConfig "zh_rCN" } 如上设置打出来的包,会包含英语、zh和zh_rCN语言的apk
7,动态库打包配置
目前Android打包可以支持如下CPU架构
armeabi-v7a 第七代 ARM v7,使用硬件浮点运算,具有高级扩展功能(支持armeabi和armeabi-v7a,目前大部分手机都是这个架构) arm64-v8a 第8代,64位,包含AARch32、AA 64两个执行状态对应32、64bit(支持armeabi-v7a、armeabi和arm64-v8a) x86 intel 少数的平板应用此架构,支持armeabi(性能有所损耗)和x86 x86_64 intel 64位,少数的平板应用此架构(支持x86和x86_64)
目前市面上手机设备绝大多数都是arm架构,因此armv7a几乎兼容所有设备,大多数应用只会打包armv7a的so在Apk中,对于第三方服务,如百度地图、Bugly等会提供全平台的CPU架构,因此我们可以进行如下配置,指定直达armv7a到apk,从而减少apk大小
android {
defaultConfig {
ndk{
abifilters "armeabi-v7a"
}
}
}
对于arm64架构的设备,如果使用armv7a也能够兼容,但是不使用arm64的so性能,随着现在arm64架构设备渐渐称为主导,因此现在部分应用时长会根据设备提供不同架构的Apk安装,此时我们需要打包出针对arm64的apk与armv7a的apk,可以使用productFlavor也可以使用APK分包:splits
flavorDimensions “default”
productFlavors{
arm32{
dimension "default"
ndk{
abiFilters "armeabi-v7a"
}
}
arm64{
dimension "default"
ndk{
abiFilters "armeabi-v7a"
}
}
}
splits {
abi {
enable true
reset()
inclue 'arm64-v8a','armeabi-v7a'
universalApk true
}
}
8,使用矢量图
矢量图可以创建与分辨率无关的图标和其他可伸缩媒体,使用这些图形可以极大地减少APK占用的空间,矢量图在android中以VectorDrawable对象的形式表示,借助VectorDrawable对象,100字节的文件可以生成与屏幕大小相同的清晰图片
不股票,系统渲染每个VectorDrawable对象需要花费大量时间,而较大的图片则需要更长的时间才能显示在屏幕上,因此,建议仅在显示小图片时使用这些矢量图
其他 使用精简版本的依赖:如protobuf-lite版本,对于分模块的库按需引入,如netty分模块引入 主动移除无用代码(开启R8/Progurad自动移除) 避免使用枚举,使用@IntDef代替 不常用功能模块使用插件化加载 开启资源混淆:github.com/shwenzhang/… 支付宝删除Dex debugItem juejin.im/post/684490… 对于发布Google play的应用选择使用: AAB developer.android.google.cn/guide/app-b…