一位五年Android工程师APK体积优化的总结(被产品虐的体无完肤)
bigegpt 2024-10-04 14:01 3 浏览
面对那种无节操的产品,你们怎么办?
产品:“apk的体积是否可以优化以下,这样比较好推广!”
我:“不可以!”
产品:“apk的体积是否可以优化以下,这样比较好推广!”
我:“不可以!”
产品:“apk的体积是否可以优化以下,这样比较好推广!”
我:“我考虑一下!”
没办法面对这样的产品我们怎么能怂!老子写代码都是一把梭!!!
但是回头想想,这个和写代码有个毛线关系!!!
好了,吐槽环节到此结束!!!
今天我们就来讨论一下,apk体积优化的一些方式:
本文知识点:
apk优化的一些奇淫技巧!!!
本文分为如下几个步骤去优化,有什么不对的还请大神们见谅! 哈哈 !!
- svg的使用与优化
- Tint着色器的使用与优化
- 资源打包配置优化
- 动态库的打包配置优化
- 移除无用的资源(物理与非物理删除)
- 代码混淆
- webp转换(api等级18)
- 资源混淆
这个需要api的等级最低为18,现在基本上都可以满足需求!
这个使用的时候很简单,选中图片直接右键,conver to Webp...直接就能转换过来!越大的图片转换节约的体积也就越大!
基本上我优化的时候就从以上几个方面去进行的,在和之前没进行优化的项目比较,可以使体积减少至少30%!不信可以在你的项目中实验一下!省的说我开车不稳,翻车了!!!
1. svg的使用与优化
首先我们先来了解一下什么是svg在百度百科是这么说的!!!,其实我们只要关注主要的概念就好了!可缩放的矢量图形。其实人话就是在不同大小的地方显示不变形!具体的概念,看看百度百科就好了!!!
为了方便给大家演示!这里呢?我特意找了个网站阿里矢量图,在这个网站中你可以下载各种的矢量图,然后呢?就没有然后了。。。
下载之后呢?会有一个丑丑的ie浏览器的图标后缀为.svg的东西!这个怎么用呢?强大的android studio 为我们做好了准备工作!
res->new->vector Asset
之后会蹦出来这么个玩意
前一个红框是系统的图标,后一个是本地的图标!这样你就会生成一个以.xml为结尾的图标了!
里面的代码大概是这个样子的!
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24.0" android:viewportHeight="24.0"> <path android:fillColor="#FF000000" android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z" /> </vector>
其实里面的具体语法我也不太了解,应该是在指定区域中分成宽和高的等份,然后填充的!感兴趣的可以自己了解一下!
使用的话,和之前的src不同了!必须这样使用!
app:srcCompat="@drawable/ic_arrow_back_black_24dp"
这里很多人会有两个疑问?
- 这个和apk体积优化有个毛线关系?
- 美工往往给很多张图片,总不能一张一张转换吧?
关于上面这两个问题,我们分别来说一下:
1. 首先svg是可缩放矢量图,所以呢?你在项目中只要添加一张svg就可以替换相应的之前美工给你的一套图,一下减少了好几张图片,你说是否有关系呢?其次svg转换成xml后大小也有相应的缩减,这个真的是成倍减少大的! 但是,但是,但是。。。这个在需要适配,适配,适配!FUCK 0.0!话说Android在适配这点上真心难受!还是看解决办法吧!在你的app->build.gradle中的defaultConfig标签中添加如下内容:
//5.0的兼容适配
//5.0以下 将svg图片生成指定维度的png图片,下面写几个就会生成几个相应的图片
vectorDrawables.generatedDensities('xhdpi','xxhdpi')
//5.0以上 以上使用support-v7进行兼容
vectorDrawables.useSupportLibrary = true
这个是我找到的解决方案,但是我编译了一下试了试。如果我单写顶上那一句,会在相应的文件夹下生成出图片,但是加上后面这句,相应的图片就没有了!我就好奇了,为什么呢?然后我找到了相应的手机试了一下,加不加上面这句没有什么卵用!我是在19版本上测试的!找这样的手机真心费劲,要不是我父母我还真找不到!!!所以呢?大家斟酌一下吧!!!
2. 这个问题,大神们早就帮我们解决了!!!
下面这个是一个批量转换工具!话说没有什么事情能难倒程序员!!!(对我失效)
MegatronKing/SVG-Android
下载这个jar包->svg2vector-cli-1.0.1.jar
然后一波小命令!!!咔咔咔
java -jar svg2vector-cli-1.0.1.jar -d D:\svg -o D:\vector -d 指定svg文件所在目录 -f 指定当个svg文件 -h 设置转换后svg高 -w 设置转换后svg宽 -o 输出android vector图像目录 然后转换完成,然后复制就好了!!!
2. Tint着色器的使用与优化
大家在开发的时候不知道有没有过这种体验!在使用状态选择器的时候,需要使用两张一样颜色不同的相同图片?其实使用tint属性完全可以搞定(但是这里指的是纯色的那种图片,那种花花绿绿的你还是乖乖弄吧,除非你想把他变成纯色!)
其实真的很简单,只要在展示的图片中添加
app:tint="颜色值"
这样就可以改变图片的颜色,那么状态选择器呢?怎么用呢?其实很简单了!下面我们来看代码!
先来看看两个状态选择器的代码:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/ic_arrow_back_black_24dp" android:state_pressed="true" /> <item android:drawable="@drawable/ic_arrow_back_black_24dp" android:state_pressed="false" /> </selector>
可能你会奇怪了,为什么两个图片是一样的?看到后面你就懂了!
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:color="@android:color/white" android:state_pressed="true" /> <item android:color="@android:color/black" /> </selector>
其实原理是这样的,状态选择器的话呢?只要你通过tint的状态选择器改变图片的颜色就可以了!
但是这里面有几个点需要注意下:
- 颜色的那个状态选择器要方法color文件夹下;
- 设置tint的时候要使用app为前缀,否则5.0以下的会报错;
- 如果你设置的是svg的图片要使用srcCompat如果是正常图片使用src就好了。
基本上这层优化就到这里了!
3. 资源打包配置优化
其实这个标题说的有点大,其实就是删除不必要的语言!!!
可能你们没有留意过,在你用Android Studio查看你的apk的时候,会看到这样的东西!
在我画框的地方,有很多中语言的使用?你会好奇的问?我没有设置过语言啊?这都从哪里跑出来的呢?其实实在v7包中的!其实我们一般的应用不会涉及到这些语言的!所以我们只留下其中的一种或几种就可以了。具体怎么做呢?其实就只有一行代码。。。
在app的build.gradle中的defaultConfig中添加这样一句就可以了!
resConfigs('zh-rCN'')
这里其实你还可以添加多个,直接用逗号连接就可以了!
优化后就变成下面这个样子了!!!
4. 动态库的打包配置
其实说到动态库的话,基本上就是.so引入的动态库,其实这里有很大的优化空间!其实你可以解压比较大型的项目,其实没有那么多so文件的类型!
平时我们开发的时候,基本上都是这么写的!
sourceSets{ main{ jniLibs.srcDirs = ['libs'] } }
然后
ndk{ abiFIlters('armeabi','armeabi-v7a','xxx'....) }
是不是每次像导入百度语音等第三方库的时候,说明文档上这么写的我们也就这么弄的!但是其实我们不需要这么多的架构!
这里简单说一下常用的几个
armeabi 真机
x86 模拟器
其实我们真是开发的话,直接使用armeabi就可以了,如果你做那种定制化的apk的话,把其它的加上还可以,但是如果正常的手机应用的话,这里只需要armeabi的就可以了!
如果你怎么不知道用哪个?你把比较大的项目解压一下看看人家用哪个你就用哪个!哈哈
5. 移除无用的资源(物理与非物理删除)
5.1 物理删除(无法找回,慎用)
关于物理删除其实很多都不建议这么使用,因为这个真的没有什么节操!这里说两个问题:
- 如果你们项目没有项目管理的话,真的不建议这么使用,因为删除之后你真的找不到了!是真的找不到了(如果git的话,拉个分支使劲磕就可以)!
- 如果有反射或者动态加载id的(ids.xml)的会直接删除!可能会报错!
好了,前提说好了!别到时候后删了之后找我。。。
方案一:
Refactor->Remove Unused Resource...
这里会谈个框,会有三个选项:
- (Refactor)第一个是直接删除了
- (Preview)第二个会在下面弹出一个提醒,让你选择性的删除
- (Cancel)取消
方案二:
Analyze->Run Inspection by name
这里也会弹出个框输入
unused ressources
然后又弹出个框,这里就按照上面的圈圈点点,然后点OK这个时候你会发现底下会出现相应的无用资源这个时候你看哪个不用就直接按照右边的提示删除就好了
再次强调,这个是物理删除,删除了就没了!!!
5.2 非物理删除
其实我估计google爸爸早就考虑到这个问题了,其实还有一种非物理删除的,是在混淆的时候!相信大家在混淆的时候都写过这句吧!
shrinkResources true
开始的时候我也不知道是什么鬼,后来看别人说这个是启动资源压缩!
但是,如果你看过压缩后的apk的话,这个资源压缩是使用了一个占位符而不是把相应的文件删除!
其实这个资源压缩还有一个比较又意思的点,可以自定义要保留的内容:
res->raw->keep.xml 自定义要保留的东西
<resources tools:keep="@layout/activity_main1" 保留谁这里就可以写谁 tools:shrinkMode="strict"/>
这个是看谷歌文档中写的!但是真的不知道为什么还要保留?处于什么原因呢?还请懂的大神指点!!!
6. 代码混淆
关于这个我不准备在这里讲,代码混淆网上一搜一大把!基本上一个固定模板加上你引入的第三方库的混淆就ok了(注意实体类就好了,每次我都忘)!
7. webp转换(api等级18)
关于webp百度百科是这么解释的。 这个需要api的等级最低为18,现在基本上都可以满足需求!
这个使用的时候很简单,选中图片直接右键,conver to Webp...直接就能转换过来!越大的图片转换节约的体积也就越大!直接看相应的转换就可以了!
这里我多唠叨一句,其实有这个图片压缩网站还是不错的!每次美工给我图片的时候我都会选择压缩一下,能节省点体积!关键是这个网站可以批量上传,这个才是重点!然后你再webp就可以了!其实我个人觉得,除非引导图等...比较大的图,否则没有必要使用webp!个人感觉而已。
推荐阅读:
相关推荐
- C#.NET Autofac 详解(c# autoit)
-
简介Autofac是一个成熟的、功能丰富的.NET依赖注入(DI)容器。相比于内置容器,它额外提供:模块化注册、装饰器(Decorator)、拦截器(Interceptor)、强o的属性/方法注...
- webapi 全流程(webapi怎么部署)
-
C#中的WebAPIMinimalApi没有控制器,普通api有控制器,MinimalApi是直达型,精简了很多中间代码,广泛适用于微服务架构MinimalApi一切都在组控制台应用程序类【Progr...
- .NET外挂系列:3. 了解 harmony 中灵活的纯手工注入方式
-
一:背景1.讲故事上一篇我们讲到了注解特性,harmony在内部提供了20个HarmonyPatch重载方法尽可能的让大家满足业务开发,那时候我也说了,特性虽然简单粗暴,但只能解决95%...
- C# 使用SemanticKernel调用本地大模型deepseek
-
一、先使用ollama部署好deepseek大模型。具体部署请看前面的头条使用ollama进行本地化部署deepseek大模型二、创建一个空的控制台dotnetnewconsole//添加依赖...
- C#.NET 中间件详解(.net core中间件use和run)
-
简介中间件(Middleware)是ASP.NETCore的核心组件,用于处理HTTP请求和响应的管道机制。它是基于管道模型的轻量级、模块化设计,允许开发者在请求处理过程中插入自定义逻辑。...
- IoC 自动注入:让依赖注册不再重复劳动
-
在ASP.NETCore中,IoC(控制反转)功能通过依赖注入(DI)实现。ASP.NETCore有一个内置的依赖注入容器,可以自动完成依赖注入。我们可以结合反射、特性或程序集扫描来实现自动...
- C#.NET 依赖注入详解(c#依赖注入的三种方式)
-
简介在C#.NET中,依赖注入(DependencyInjection,简称DI)是一种设计模式,用于实现控制反转(InversionofControl,IoC),以降低代码耦合、提高可...
- C#从零开始实现一个特性的自动注入功能
-
在现代软件开发中,依赖注入(DependencyInjection,DI)是实现松耦合、模块化和可测试代码的一个重要实践。C#提供了优秀的DI容器,如ASP.NETCore中自带的Micr...
- C#.NET 仓储模式详解(c#仓库货物管理系统)
-
简介仓储模式(RepositoryPattern)是一种数据访问抽象模式,它在领域模型和数据访问层之间创建了一个隔离层,使得领域模型无需直接与数据访问逻辑交互。仓储模式的核心思想是将数据访问逻辑封装...
- C#.NET 泛型详解(c# 泛型 滥用)
-
简介泛型(Generics)是指在类型或方法定义时使用类型参数,以实现类型安全、可重用和高性能的数据结构与算法为什么需要泛型类型安全防止“装箱/拆箱”带来的性能损耗,并在编译时检测类型错误。可重用同一...
- 数据分析-相关性分析(相关性 分析)
-
相关性分析是一种统计方法,用于衡量两个或多个变量之间的关系强度和方向。它通过计算相关系数来量化变量间的线性关系,从而帮助理解变量之间的相互影响。相关性分析常用于数据探索和假设检验,是数据分析和统计建模...
- geom_smooth()函数-R语言ggplot2快速入门18
-
在每节,先运行以下这几行程序。library(ggplot2)library(ggpubr)library(ggtext)#用于个性化图表library(dplyr)#用于数据处理p...
- 规范申报易错要素解析(规范申报易错要素解析)
-
为什么要规范申报?规范申报是以满足海关监管、征税、统计等工作为目的,纳税义务人及其代理人依法向海关如实申报的行为,也是海关审接单环节依法监管的重要工作。企业申报的内容须符合《中华人民共和国海关进出口货...
- 「Eurora」海关编码归类 全球海关编码查询 关务服务
-
海关编码是什么? 海关编码即HS编码,为编码协调制度的简称。 其全称为《商品名称及编码协调制度的国际公约》(InternationalConventionforHarmonizedCo...
- 9月1日起,河南省税务部门对豆制品加工业试行新政7类豆制品均适用投入产出法
-
全媒体记者杨晓川报道9月2日,记者从税务部门获悉,为减轻纳税人税收负担,完善农产品增值税进项税额抵扣机制,根据相关规定,结合我省实际情况,经广泛调查研究和征求意见,从9月1日起,我省税务部门对豆制品...
- 一周热门
- 最近发表
- 标签列表
-
- mybatiscollection (79)
- mqtt服务器 (88)
- keyerror (78)
- c#map (65)
- xftp6 (83)
- bt搜索 (75)
- c#var (76)
- xcode-select (66)
- mysql授权 (74)
- 下载测试 (70)
- linuxlink (65)
- pythonwget (67)
- androidinclude (65)
- libcrypto.so (74)
- linux安装minio (74)
- ubuntuunzip (67)
- vscode使用技巧 (83)
- secure-file-priv (67)
- vue阻止冒泡 (67)
- jquery跨域 (68)
- php写入文件 (73)
- kafkatools (66)
- mysql导出数据库 (66)
- jquery鼠标移入移出 (71)
- 取小数点后两位的函数 (73)