APP终极瘦身方案

具体可参见 github.com/shwenzhang/…

优化META-INF

MANIFEST.MF:是摘要文件,程序会遍历apk包中所有的文件,对非文件夹、非签名文件的文件,逐个编码生成摘要信息,并记录于此。如果逆向修改了任何文件,那么将出现文件和摘要信息不匹配的情况,导致安全校验失败。每一个资源文件都有一个sha1-digest的值,为该文件sha-1的值进行base64编码后的结果。

CERT.SF:是对MANIFEST.MF的签名文件,经过三步生成:

  • 1、系统会把MANIFEST.MF整个文件进行sha1计算,并且计算base64编码后的值。

  • 2、系统会对MANIFEST.MF中的每一条内容分别进行sha1计算,然后再用base64编码。

  • 3、上述两部完成后,系统会将内容写入到CERT.SF文件中。

可以这样理解CERT.SF的作用:

  • 该文件是MANIFEST.MF的二次编码后产生的文件。

  • 如果逆向修改了任何文件,则MANIFEST.MF文件必定会发生改变,从而和CERT.SF不匹配。

  • CERT.SF二次编码的特点是用于在APK安装时校验MANIFEST.MF是否被篡改

  • 若根据修改的文件伪造了一份新的CERT.SF文件,那么数字签名值必定与CERT.RSA中的记录不一样

CERT.RSA:包含了公钥和加密算法等信息,而最重要的信息是“对CERT.SF用私钥进行加密之后的值”。

META-INF文件夹下的文件环环相扣,总结如下:

  • 如果逆向修改了APK包中的文件,那么被修改的文件的摘要和MANIFEST.MF中的信息则不对应

  • 如果修改了某个文件,则必须修改MANIFEST.MF中对应的摘要值,必须保证对应关系

  • 要修改MANIFEST.MF的摘要值,会产生新的MANIFEST.MF,必然和CERT.SF中的记录不匹配

  • CERT.SF中记录了MANIFEST.MF整个文件的编码和其所有内容的编码值,逆向时必须修改CERT.SF

  • 修改了CERT.SF后,安装apk时CERT.RSA文件中的内容和修改后的CERT.SF会不匹配,出现安装失败

  • 逆向者只有拿到了开发者的秘钥才能完全创造一个相同的apk

优化建议:通过分析得出,除了RSA没有缩减机会外,其余两个文件都可以通过混淆资源名称的方式进行压缩。

优化Res目录
  • 打包时剔除无用资源:shrinkResources true shrinkResources意思是收缩资源,将它设置为true,每次打包时就会自动排除无用的资源,不仅作用于图片,还会清理无用的layout资源等,但是只有配合开启混淆才能生效。

  • 删除无用的语言:大部分app其实不需要支持几十种语言,国内应用,可以只支持中文

defaultConfig {

resConfig “zh”

}

这样配置后,打包时会排除私有项目、Android support库、三方库中的非中文资源文件。

  • 控制raw中的资源大小:Raw和Assets可以用来存放资源,但两者有以下差异:
  1. Assets目录允许下面有多级子目录,而Raw不允许存在字目录结构。

  2. Assets目录不会产生R文件,Raw则相反

  3. 因为Raw文件会产生R文件的映射,所以可以被lint分析,而Assets不能

  4. Raw不支持子目录让其无法成为存放多种类文件的目录

Raw虽然不会对文件大小有限制,但是存放的音频文件尽量不要使用无损格式,可以考虑同等质量但文件更小的音频格式,如OGG、wav、mp3等格式

减少layout文件

减少layout有两个方法:复用和融合。

复用:把一些页面共用的布局抽出来,这对于layout文件的管理还是瘦身都非常有用。

融合:对于不会被复用的layout呢?

  • shatter是一个类似于Fragment的解耦库,可以为同一个layout中不同区域的view进行逻辑解耦,还可以尽可能少的建立layout文件。

  • 将没有必要复用的header头布局和ListView/RecycleView放在同一个layout布局中,通过代码完成头部的添加

动态下载图片

贴纸、表情这类的文件是相当大的,对于这类图片资源,强烈建议通过在线的方式获取,虽然有一点的复杂度和出错率,但是投入产出比还是不错的。

分目录放置图片

不同分辨率的图片应该放在不同的目录中,如果放错了,对于app运行时的内存大小会有一定的影响。

如果把一个本来应该放在drawable-xxhdpi里面的图片放在了drawable文件夹中,会出现什么问题呢? 在xxhdpi设备上,图片会放大3倍,图片内存占用会变为原来的9倍。

因为不同分辨率的图片大小有差距,很多认为可以使用一套图片来做,不用多套图,借此达到瘦身的目的。但谷歌建议针对不同分辨率出不同的图片。 比较通用的做法是:

  • 聊天表情就出一套图,放在hdpi中(因为此类图片对于清晰度要求不高)

  • 纯色小icon用svg制作,用矢量图适配所有分辨率

  • 对于背景图等大图,出一套放在hdpi或者xxhdpi中

  • logo等权重较大的图片可针对hdpi、xhdpi、xxhdpi做多套图

  • 如果某些图在真机中展示异常,就用多套图适配

  • 如果有特殊机型,可针对性的补图

优化图片资源

图片的优化,最重要的是知道选择什么样的图片格式。

  • 如果是纯色的icon,推荐使用svg

  • 如果是两种以上颜色的icon,推荐使用webp

  • 如果webp无法达到效果,则选择用png

  • 如果图片没有alpha通道,则考虑使用jpg

  • 因为svg是通过xml描述的,所以可以享受到资源优化和代码压缩,通常可以压缩到1kb

  • 对于无透明度的大图,可以换为jpg格式进行有损压缩

webp格式从4.0开始原生支持,知道4.2.1才支持显示含有透明度的webp,一般png转换为webp,大小可以减少一半

另外,在大型项目中,会引入汗多support库以及三方库,如果库中包含一些大图,并且不会用到的话,可以用1x1的同名透明图片替代,达到技能编译通过,又能缩小体积的目的。

针对动画,尤其是帧动画,一直是相当占用资源的,现在可以使用svg动画或者Airbnb公司的Lottie动画库实现,如果使用Lottie可以直接使用json文件描述动画,图片会减少很多。

优化dex

dex文件是class文件被编译后可供art虚拟机理解的文件格式,可以理解为java代码包。

利用lint分析无用代码

可以借助Inspect Code,对工程做静态代码检查。Lint是一个强大的工具,它能做的事情不限于检查无用资源和代码,它能检测丢失的属性、写错的单位、会引起内存溢出的代码等,当然Lint虽然强大,但也会带来一些缺点,就是生成的信息量过大,不适合快速定位无用的代码。除此之外,Lint会提示不要使用枚举方法,如果将枚举变为int,apk的大小也会缩小一些,没减少一个enum,可以减少大约1到4kb的大小。

image.png

删除R文件

Android中的R文件,除了styleable类型外,所有的字段都是int型变量或者常量,且在运行期间都不会改变。可以在编译时记录R中所有字段的名称以及对应值,然后利用ASM工具遍历所有class,将引用R字段的地方替换成对应的常量 ThinRPlugin插件可以方便地将R.xxx的地方替换为具体值,可以减少一部分dex大小。

在最外层的build.gradle中加入如下依赖:

classpath ‘com.mogujie.gradle:ThinRPlugin:0.0.2’

在内层的gradle文件中加入如下代码:

apply plugin: ‘thinR’

thinR {

//为了不影响日常开发的编译速度,debug版本可以不用删除R

skipThinRDebug = true

}

启用ProGuard:

ProGuard是一款优秀的代码优化、混淆工具,适用于java和Android。关于ProGuard,最需要了解的是它的方法检测机制。它将产出的class作为输入,然后寻找代码中所有的调用点,计算出代码中可达的调用关系图,然后移出剩余的部分,将真正用到的方法变量保留下来进行优化,最终输出一个新的class。

image.png

上图简单描述了什么是可达和不可达的代码

buildTypes {

release {

minifyEnabled true

shrinkResources true //压缩资源

proguardFiles getDefaultProguardFile(‘proguard-android-optimize.txt’), ‘proguard-rules.pro’

}

}

虽然这种​
方式成果显著,但也要配合正确的ProGuard规则才能起作用。

image.png

这张图展示了原始apk和混淆后apk的大小差异

每次构建时,ProGuard都会输出下列文件:

  • dump.txt:说明APK中所有类文件的内部结构

  • mapping.txt:提供原始与混淆过的类、字段、属性、方法之间的映射关系

  • seeds.txt:列出未进行混淆的类和成员

  • usage.txt:列出从apk中移除的类和代码

利用混淆来删除代码的方式是一种保险措施,真正治本的方法是在开发过程中随手删除无用的代码。

最后

小编这些年深知大多数初中级Android工程师,想要提升自己,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助

因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

资料⬅专栏获取
是一种保险措施,真正治本的方法是在开发过程中随手删除无用的代码。

最后

小编这些年深知大多数初中级Android工程师,想要提升自己,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助

因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。

[外链图片转存中…(img-HmvSa9dR-1719087128977)]一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

资料⬅专栏获取

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/735287.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

异地数据中心的数据实时同步,该怎样智能化实现?

为了提高系统的可用性和容错性,越来越多的企业和机构采用两地三中心方案等来进行异地数据中心的建设。数据中心建立后,数据需要同步至总部或其他数据中心及系统,以确保数据的冗余性、可用性、可靠性和一致性。在分布式系统、云计算、容灾备份…

游戏工厂:AI(AIGC/ChatGPT)与流程式游戏开发

游戏工厂:AI(AIGC/ChatGPT)与流程式游戏开发 码客 卢益贵 ygluu 关键词:AI(AIGC、ChatGPT、文心一言)、流程式管理、好莱坞电影流程、电影工厂、游戏工厂、游戏开发流程、游戏架构、模块化开发 一、前言…

3D开发工具HOOPS为BIM应用提供支持:复杂大模型实现Web端轻量化!

在数字化转型的浪潮中,Tech Soft 3D以其HOOPS SDK工具包,为软件开发人员提供了强大的支持。这一工具包不仅支持Windows、Linux、OSX和移动平台等多样化的操作系统,还使得开发人员能够构建出庞大而复杂的建筑和BIM应用程序。HOOPS SDK的多格式…

RIP动态路由配置

1、搭建网络 搭建拓扑、规划IP地址、划分网段、设置端口 2、配置交换机,路由器 三层交换机配置 Switch>enable Switch#conf t Enter configuration commands, one per line. End with CNTL/Z. Switch(config)#hostname S3560S3560(config)#vlan 10 S3560(con…

fot循环语句

概念: 循环是一种重复执行一段代码的结构,只要满足循环的条件,会一种执行这个代码。 循环条件:在一定范围内,按照指定的次数来执行循环 循环体:在指定的次数内,执行的命令序列。只要条件满足…

GD32F4xx 移植agile_modbus软件包与电能表通信

目录 1. agile_modbus1.1 简介1.2 下载2. agile_modbus使用2.1 源码目录2.2 移植3. 通信调试3.1 代码3.3 通信测试1. agile_modbus 1.1 简介 agile_modbus是一个轻量级的Modbus协议栈,主要特点: 支持RTU和TCP协议,采用纯C语言开发,不涉及任何硬件接口,可直接在任何形式的…

2024年【N1叉车司机】考试及N1叉车司机考试题库

题库来源:安全生产模拟考试一点通公众号小程序 N1叉车司机考试是安全生产模拟考试一点通总题库中生成的一套N1叉车司机考试题库,安全生产模拟考试一点通上N1叉车司机作业手机同步练习。2024年【N1叉车司机】考试及N1叉车司机考试题库 1、【多选题】《中…

一站式实时数仓Hologres整体能力介绍

讲师:阿里云Hologres PD丁烨 一、产品定位 随着技术的进步,大数据正从规模化转向实时化处理。用户对传统的T1分析已不满足,期望获得更高时效性的计算和分析能力。例如实时大屏,城市大脑的交通监控、风控和实时的个性化推荐&…

计算机专业:昔日万金油,明日科技潮头的弄潮儿

高考后的十字路口:计算机专业,依旧闪耀吗? 随着2024年高考的尘埃落定,数百万青春洋溢的脸庞再次凝视着未来的迷雾,试图在繁星点点的专业宇宙中找到那颗最亮的星——计算机科学与技术。长久以来,计算机专业…

如何在Windows 11和10上清除更新缓存?这里提供了几种方法

​Windows 11和Windows 10都可以非常轻松地清除Windows更新缓存。可以使用图形方法或命令行选项删除保存的更新文件。我们将向你展示你的可用选项。 为什么要清除Windows更新缓存 你可能希望清除Windows更新缓存的原因有很多。 你可能在查找或安装更新时遇到问题,清除缓存通…

ansible 模块进阶及变量

yum 模块进阶 - name: install pkgs hosts: webservers tasks: - name: install web pkgs # 此任务通过yum安装三个包 yum: name: httpd,php,php-mysqlnd state: present # 根据功能等,可以将一系列软件放到一个组中,安装软件包组,将会把很…

IK分词器---Elasticsearch(standard、ik_smart、ik_max_word、拓展词典---ik_max_word)

IK分词器 Elasticsearch的关键就是倒排索引,而倒排索引依赖于对文档内容的分词,而分词则需要高效、精准的分词算法,IK分词器就是这样一个中文分词算法。 1.4.1.安装IK分词器 方案一:在线安装 运行一个命令即可: do…

稳态与敏态业务阶段

稳态业务就是比如你登录学校的图书馆教务处这些业务系统 用户数量和数据基本上不会发生太大的变化 业务系统的更新也不是很频繁,比较方便资源的采购 敏态业务就是比如我开发一个应用上线了,我不知道有多少用户和数量,无法预估 这就没办法…

ru俄罗斯域名如何申请SSL证书?

我们日常看到的都是com这种国际域名比较普遍,尤其是主流网站,主要原因考虑的其通用性,那么对于地方性的域名大家很少看到,比如俄罗斯国家域名.ru大家还是有些陌生的,但要说中国.CN域名那你就很熟悉了。 有用户在申请过…

python子类调用其他.py文件的父类

main.py需要使用os.py中的构造类。 os.py中定义了一个Ui_MainWindow类 在main.py中定义了一个MyMainWindow子类,传入两个父类的变量名 super(Ui_MainWindow, self).__init__()super() super() 是一个内置函数,用于返回一个代表父类的对象,…

使用Mysql模糊查询指定多个字段条件,输出结果的详细教程!

本篇文章主要讲解:通过mysql实现对多个列字段进行模糊查询的方式说明,通过本篇文章你可以快速掌握对多条件查询的方法 日期:2024年6月22日 作者:任聪聪 一、准备工作 步骤一、新建一个test数据库,如下图: …

使用C语言实现植物大战僵尸教程

Hi~!这里是奋斗的小羊,很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~~ 💥💥个人主页:奋斗的小羊 💥💥所属专栏:C语言 🚀本系列文章为个人学习…

如何使用kimi智能助手:您的智能生活小助手

Kimi智能助手是一款功能强大的AI工具,旨在帮助用户提高工作效率和生活品质。下面小编将详细介绍如何使用Kimi智能助手,涵盖其主要功能以及一些实用技巧。 一、Kimi智能助手的主要功能 多语言对话能力:Kimi擅长中文和英文的对话,可…

Ubuntu编译安装sqlite3库

基础环境说明:本机使用Windows 11 家庭版本搭载 Ubuntu 22.04.4 LTS 子系统。进行sqlite3 数据库源码编译和库函数生成。 sqlite3的简介 什么是SQLite3? sqlite3是一个进程内的库,实现了自给自足、无服务器、零配置、事务性的SQL数据库引擎…

[手机Linux PostmarketOS]一,1加6T真正的手机Linux系统

前面用Linux deploy软件安装了Linux系统在手机,实则不是真正的手机刷成了linux系统,而是通过Linux deploy软件在容器里安装了Linux系统,在使用方面会有诸多限制,并不能发挥Linux的真实强大之处,于是我又百度又谷歌(真不…