我的编程空间,编程开发者的网络收藏夹
学习永远不晚

APK体积优化(附Android Studio操作指引)

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

APK体积优化(附Android Studio操作指引)

目录

1. 压缩APK体积的意义

2. APK的构成与打包

3. res资源的压缩和优化

3.1 删除没有被引用的资源

3.2 使用WebP压缩图片

3.3 使用TinyPNG压缩图片

4. 删除多余的代码(未被引用的类/方法/变量)

4.1 代码混淆

4.2 利用Lint查找无用代码

5. Zip格式优化

6. classes.dex优化

7. lib优化

8. 参考资料

1. 压缩APK体积的意义 随着项目的不断迭代,功能越来越多,构建出来的apk文件的大小也会越来越大,这样会导致在移动网络情况下下载时,使用的网络流量会增大,并且apk太大,导致下载的时间也增加,虽然当前每个人的手机的流量都很多,对用户流量影响不大,但是据一些网站统计,安装包越大,用户的转化率是在降低的,所以减少apk的体积,可以让更多的用户愿意去下载和体验产品;[1] 压缩APK体积还有个很重要的意义在于节省手机的内存空间以及存储空间,APK体积压缩之后,运行APP时的资源加载少了,占用的手机内存也会变少,整体运行更为流畅; 对于一些功能比较丰富的软件可能内部采用了多插件的架构,而这些插件可能也是由一个个独立APK组成,那么在用户下载软件后第一次使用插件对应的功能时,也就是冷启动的时候,APK太大就会带来加载过慢的问题,会严重影响用户体验。 2. APK的构成与打包

这里拿自己的一个Demo编译生成的release版本的APK作为例子,来看看一个APK里面到底装了什么:

这里详细介绍一下APK里面的组成:[2]

lib:存放so文件,可能会有armeabi、armeabi-v7a、arm64-v8a、x86、x86_64、mips,大多数情况下只需要支持armabi与x86的架构即可,如果非必需,可以考虑拿掉x86的部分; res:存放编译后的资源文件,例如:drawable、layout等等; assets:应用程序的资源,应用程序可以使用AssetManager来检索该资源; META-INF:该文件夹一般存放于已经签名的APK中,它包含了APK中所有文件的签名摘要等信息; kotlin:这些文件包含用于声明标准(“内置”)Kotlin类的数据,这些类未编译为.class文件,而是映射到平台上的现有类型(在本例中为JVM)。例如,kotlin / kotlin.kotlin_builtins包含kotlin包中的非物理类的信息:Int,String,Enum,Annotation,Collection等; classes(n).dex:classes文件是Java Class,被DEX编译后可供Dalvik/ART虚拟机所理解的文件格式; resources.arsc:编译后的二进制资源文件; AndroidManifest.xml:Android的清单文件,格式为AXML,用于描述应用程序的名称、版本、所需权限、注册的四大组件。

这里补充一下App资源被打包进APK的过程,Android构建工具链使用AAPT工具来对资源进行处理,来看下图:

3. res资源的压缩和优化 3.1 删除没有被引用的资源

一个Android项目中或多或少都会存在没被引用的资源文件,Android Studio就内置了查找无效资源的Lint工具,下面还是以Demo作为例子介绍一下具体的操作步骤:

步驟一:在上方菜单栏点击Analyze -> Run Inspection by Name...

步骤二:搜索unused resourses

步骤三:设置并开始检查资源

Lint工具运行完后就会展示出项目中没有被引用过的资源文件列表,然后就可以开始移除这些文件:

3.2 使用WebP压缩图片

WebP是一种同时提供了有损压缩与无损压缩(可逆压缩)的图片文件格式,派生自影像编码格式VP8,被认为是WebM多媒体格式的姊妹项目。WebP最初由Google在2010年发布,目标是减少文件大小,但达到和JPEG格式相同的图片质量,希望能够减少图片档在网络上的发送时间。[3]

根据Google较早的测试,WebP的无损压缩比网络上找到的PNG档少了45%的文件大小,即使这些PNG档在使用pngcrush和PNGOUT处理过,WebP还是可以减少28%的文件大小。[4]

安卓:Android 4.0(API级别14)及更高版本支持有损WebP图像,Android 4.3(API级别18)及更高版本支持无损和透明的WebP图像。

IOS:当前的iOS不支持webp,不知道以后会不会支持,所以从网络上拿到一个webp格式的图片后,并不能直接显示出来,需要把data数据转化为jpg或者png来显示。

下面讲讲Android Studio内置的webp转换工具以及操作步骤:

步骤一:右键要转换的图片,选择convert to webp...

步骤二:设置并开始转换

3.3 使用TinyPNG压缩图片

TinyPNG是免费的在线图片无损压缩工具,压缩效果亲测不错,推荐给大家:

4. 删除多余的代码(未被引用的类/方法/变量) 4.1 代码混淆

混淆代码并不是让代码无法被反编译,而是将代码中的类、方法、变量等信息进行重命名,把它们改成一些毫无意义的名字,同时也可以移除未被使用的类、方法、变量等。 所以直观的看,通过混淆可以提高程序的安全性,增加逆向工程的难度,同时也有效缩减了apk的体积。主要作用如下:[5]

将项目中的类、方法、变量等信息进行重命名,变成一些无意义的简短名字; 移除未被使用的类、方法、变量等;

在APP的主Module下的gradle文件中做如下配置:[1]

buildTypes { 
	release { 
		//开启代码混淆 
		minifyEnabled true 
		//Zipalign优化 
		zipAlignEnabled true 
		//移除无用的resource文件 
		shrinkResources true 
		proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
	} 
} 

使用 shrinkResources 进行移除,但使用 shrinkResources 必须先开启代码混淆 minifyEnabled。

除了minifyEnabled属性外,还有用于定义ProGuard规则的proguardFiles属性:

getDefaultProguardFile(‘proguard-android.txt')
是从Android SDK的
tools/proguard/
文件夹获取默认ProGuard设置。
proguard-rules.pro
文件用于添加自定义ProGuard规则。默认情况下,该文件位于模块根目录(build.gradle文件旁)。

注意:代码压缩会拖慢构建速度,因此应该尽可能避免在调试构建中使用。不过一定要为用于测试的最终APK启用代码压缩,如果不能充分地自定义要保留的代码,可能会引入错误。

4.2 利用Lint查找无用代码

类似上面的利用Lint查找未引用资源,点击菜单栏的Analyze -> Analyze -> Run Inspection by Name...

搜索unused declaration,如下所示:

搜索结果会把没有引用过的类/方法/变量列出来,然后就可以考虑移除这些无用的代码:

5. Zip格式优化

通过 aapt l -v xxx.apk 或者 unzip -l xxx.apk 可以查看APK的详细信息:

通过上图可以看到APK中很多资源是以

Stored
来存储的,这些文件是没有压缩的。从AAPT的源码中找到以下描述:



static const char* kNoCompressExt[] = {
    ".jpg", ".jpeg", ".png", ".gif",
    ".wav", ".mp2", ".mp3", ".ogg", ".aac",
    ".mpg", ".mpeg", ".mid", ".midi", ".smf", ".jet",
    ".rtttl", ".imy", ".xmf", ".mp4", ".m4a",
    ".m4v", ".3gp", ".3gpp", ".3g2", ".3gpp2",
    ".amr", ".awb", ".wma", ".wmv", ".webm", ".mkv"
};

可以看出AAPT在资源处理时对这些文件后缀类型的资源是不做压缩的,那是不是可以修改它们的压缩方式从而达到瘦身的效果呢?详细压缩方法可以参考:美团技术团队-Android App包瘦身优化实践

6. classes.dex优化

如何优化classes.dex的大小,大体有如下两个方向:[2]

时刻保持良好的编程习惯和对包体积敏锐的嗅觉,去除重复或者不用的代码,慎用第三方库,选用体积小的第三方SDK等等; 开启ProGuard来进行代码压缩,通过使用ProGuard来对代码进行混淆、优化、压缩等工作。 7. lib优化

在开发android应用的时候,你经常会使用外部的library库来提升你app的可用性和扩展性。例如,你会引入Android Support Library来提升用户在旧机型上面的体验,或者你会使用Google Play Service来自动翻译你app中的文本。如果一个library库被设计为一个服务或者桌面,那么它就会包含很多你应用没有用到的对象和方法。为了只包含你工程中用到的部分,你可以修改这个库文件,如果license许可的话,同时你也可以使用另外的移动端友好的库来给你的app增加特定的功能。[6]

注意:Progard能清除导入库中一些无用的代码,但是不能清除库中大的内部依赖。

GitHub上有一个开源方案 - upx:https://github.com/upx/upx

upx简介(50%~70%压缩率):

UPX is an advanced executable file compressor. UPX will typically
reduce the file size of programs and DLLs by around 50%-70%, thus
reducing disk space, network load times, download times and
other distribution and storage costs.
Programs and libraries compressed by UPX are completely self-contained
and run exactly as before, with no runtime or memory penalty for most
of the supported formats.
8. 参考资料

[1] 知乎-专栏-Andriod APK体积优化

[2] 美团技术团队-Android App包瘦身优化实践

[3] 维基百科-WebP

[4] 百度百科-webp格式

[5] 掘金-Android代码混淆详解

[6] 简书-性能优化(6)-减小APK体积


作者:VG-Lin


免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

APK体积优化(附Android Studio操作指引)

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

APK体积优化(附Android Studio操作指引)

目录 1. 压缩APK体积的意义 2. APK的构成与打包 3. res资源的压缩和优化 3.1 删除没有被引用的资源 3.2 使用WebP压缩图片 3.3 使用TinyPNG压缩图片 4. 删除多余的代码(未被引用的类/方法/变量) 4.
2022-06-06

编程热搜

  • Android:VolumeShaper
    VolumeShaper(支持版本改一下,minsdkversion:26,android8.0(api26)进一步学习对声音的编辑,可以让音频的声音有变化的播放 VolumeShaper.Configuration的三个参数 durati
    Android:VolumeShaper
  • Android崩溃异常捕获方法
    开发中最让人头疼的是应用突然爆炸,然后跳回到桌面。而且我们常常不知道这种状况会何时出现,在应用调试阶段还好,还可以通过调试工具的日志查看错误出现在哪里。但平时使用的时候给你闹崩溃,那你就欲哭无泪了。 那么今天主要讲一下如何去捕捉系统出现的U
    Android崩溃异常捕获方法
  • android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
    系统的设置–>电池–>使用情况中,统计的能耗的使用情况也是以power_profile.xml的value作为基础参数的1、我的手机中power_profile.xml的内容: HTC t328w代码如下:
    android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
  • Android SQLite数据库基本操作方法
    程序的最主要的功能在于对数据进行操作,通过对数据进行操作来实现某个功能。而数据库就是很重要的一个方面的,Android中内置了小巧轻便,功能却很强的一个数据库–SQLite数据库。那么就来看一下在Android程序中怎么去操作SQLite数
    Android SQLite数据库基本操作方法
  • ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
    工作的时候为了方便直接打开编辑文件,一些常用的软件或者文件我们会放在桌面,但是在ubuntu20.04下直接直接拖拽文件到桌面根本没有效果,在进入桌面后发现软件列表中的软件只能收藏到面板,无法复制到桌面使用,不知道为什么会这样,似乎并不是很
    ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
  • android获取当前手机号示例程序
    代码如下: public String getLocalNumber() { TelephonyManager tManager =
    android获取当前手机号示例程序
  • Android音视频开发(三)TextureView
    简介 TextureView与SurfaceView类似,可用于显示视频或OpenGL场景。 与SurfaceView的区别 SurfaceView不能使用变换和缩放等操作,不能叠加(Overlay)两个SurfaceView。 Textu
    Android音视频开发(三)TextureView
  • android获取屏幕高度和宽度的实现方法
    本文实例讲述了android获取屏幕高度和宽度的实现方法。分享给大家供大家参考。具体分析如下: 我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现。下面就介绍讲一讲如何获取屏幕的物理尺寸 下面的代码即
    android获取屏幕高度和宽度的实现方法
  • Android自定义popupwindow实例代码
    先来看看效果图:一、布局
  • Android第一次实验
    一、实验原理 1.1实验目标 编程实现用户名与密码的存储与调用。 1.2实验要求 设计用户登录界面、登录成功界面、用户注册界面,用户注册时,将其用户名、密码保存到SharedPreference中,登录时输入用户名、密码,读取SharedP
    Android第一次实验

目录