Android性能优化之应用瘦身(APK瘦身)

2023-11-06

关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。
专注于分享各领域原创系列文章 ,擅长java后端、移动开发、人工智能等,希望大家多多支持。

在这里插入图片描述

一、导读

我们继续总结学习Android 知识,温故知新。

lint检查代码

二、概览

APK瘦身优化的优先级相对来说是比较低的,因为优化后也并不能明显的看到有什么好处,这一块主要影响转换率,应用越小,
可能用户下载的意愿就越高,另外在进行预装时,也有大小的要求。

一般来说我们可以通过下面几种方式来进行优化:

  • 资源文件:压缩;动态下载。
  • so文件:动态so;不同的架构支持(v7a、v8a)。
  • 源代码:用代码分析工具,去除不再使用的代码;插件化。
  • assets:动态下载;压缩。
  • proguard 混淆代码

2.1 apk组成

直接将apk 拖到android studio窗口,或者我们把apk解压后,能看到下面这些文件

文件 描述
classes(有多个).dex Java Class,被DEX编译后可供Dalvik/ART虚拟机所理解的文件格式
lib 存放so文件,可能有多种架构
assets 程序资源,使用AssetManager来调用
res 资源文件,如:drawable、layout
AndroidManifest AndroidManifest
resources.arsc 编译后的二进制资源文件
META-INF 包含了APK中所有文件的签名摘要等信息

三、优化方向

我们的优化方案,就对应这apk的组成

3.1 源代码

3.1.1 代码混淆

3.1.2 移除无用代码

  1. studio 自带的工具
    在这里插入图片描述

  2. 使用CPD/PMD工具
    PMD是一个源代码分析器。它发现常见的编程缺陷,如未使用的变量、空的catch块、不必要的对象创建,等等.
    PMD 网站
    PMD GUI网站:

  3. 使用切面编程的方式进行统计(AOP),确认无用代码。

3.1.3 三方库的处理

统一基础库
统一三方调用的库等等

原则是同样的功能,不要出现多套代码。

3.2 资源文件

  1. 删除冗余资源

  2. 资源混淆

  3. 资源压缩

    • jpg:采取压缩算法,不支持透明通道
    • png:无损压缩,支持透明度
    • webp:无损压缩图像格式,与JPG相比,可大幅减少文件体积

虽然png是无损压缩。但是也有一些网站可以对png图片进行有损压缩,比如tinypng网站

  1. 资源在线化,动态下载
    对于一些比较大,又不是很及时要用的图片,可以考虑从服务端下载。

可以使用下面三种方式找出无用的资源

3.2.1 方式一 Inspect Code

  1. 通过Android Studio 菜单栏 → code → Inspect Code
  2. 在弹出的框框中选择 configure (在右下键)
  3. 在弹出的框框中输入 unused resources(在左上角),勾选对应的选项
  4. 点击开始

如下图
在这里插入图片描述

这里的选项实在是很多,我们只找出未使用的资源文件,最好先将其他的选择全取消,然后在勾选 unused resources
在这里插入图片描述

这时候就开始分析项目了,我们耐心等待一会
在这里插入图片描述

3.2.2 方式二

菜单栏 → Refactor → Remove Unused Resources
在这里插入图片描述

这样直接就开始删了,当然要检查下,不要误删。

3.2.3 方式三 腾讯的 Matrix

Matrix是微信终端自研和正在使用的一套APM(Application Performance Management)系统。
Matrix-ApkChecker 作为Matrix系统的一部分,是针对android安装包的分析检测工具,根据一系列设定好的规则检测apk是否存在特定的问题,
并输出较为详细的检测结果报告,用于分析排查问题以及版本追踪。Matrix-ApkChecker以一个jar包的形式提供使用,
通过命令行执行 java -jar ApkChecker.jar 即可运行。

也可以配置一下

java -jar matrix-apk-canary-2.1.0.jar --config CONFIG-FILE-PATH

matrix git 搜索APK Checker,这里有个下载链接,点击下载jar包。

Matrix apkchecker 文档

CONFIG.json文件,也可以之间用官网的,最终会生成两个文件,之间查看即可

{
  "--apk":"E:\\release.apk",
  "--mappingTxt":"E:\\mapping.txt",
  "--output":"E:\\",
  "--format":"mm.html,mm.json",
  "--formatConfig":
  [
    {
      "name":"-countMethod",
      "group":
      [
        {
          "name":"Android System",
          "package":"android"
        },
        {
          "name":"java system",
          "package":"java"
        },
        {
          "name":"com.tencent.test.$",
          "package":"com.tencent.test.$"
        }
      ]
    }
  ],
  "options": [
    {
      "name":"-manifest"
    },
    {
      "name":"-fileSize",
      "--min":"10",
      "--order":"desc",
      "--suffix":"png, jpg, jpeg, gif, arsc"
    },
    {
      "name":"-countMethod",
      "--group":"package"
    },
    {
      "name":"-checkResProguard"
    },
    {
      "name":"-findNonAlphaPng",
      "--min":"10"
    },
    {
      "name":"-checkMultiLibrary"
    },
    {
      "name":"-uncompressedFile",
      "--suffix":"png, jpg, jpeg, gif, arsc"
    },
    {
      "name":"-countR"
    },
    {
      "name":"-duplicatedFile"
    },
    {
      "name":"-unusedResources",
      "--rTxt":"E:\\R.txt",
      "--ignoreResources"
      :["R.raw.*",
        "R.style.*",
        "R.attr.*",
        "R.id.*",
        "R.string.ignore_*",
        "R.dimen.*",
        "R.string.*",
        "R.color.*"
      ]
    },
    {
      "name":"-unusedAssets",
      "--ignoreAssets":["*.so" ]
    }
  ]
}

通过这种方式,我们回得到一个html分析的结果表格,但是我们看到的都是混淆过到资源文件,这时 可以使用 aapt2 来输出apk资源表的内容(resources.arsc文件):

aapt2 dump resources xxx.apk > logx.txt

3.2.4 资源混淆

3.3 so瘦身

动态so;
指定架构支持(如v7a、v8a);

另外还可以只保留一个cpu架构,别的cpu架构自动适配,程序运行过程中,通过判断cpu架构选择合适的so

if(v7a) {
    xxx
} else {
    xxx
}

还有就是插件化,这个是一个专题,我们在另外的文章里面讲。

四、 推荐阅读

Java 专栏

SQL 专栏

数据结构与算法

Android学习专栏

ddd

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android性能优化之应用瘦身(APK瘦身) 的相关文章

  • getItem 与 getItemAtPosition

    有两种方法可以获取列表视图中的选定项目 list getAdapter getItem position list getItemAtPosition position 我的问题是 哪一种是首选的做法 我见过人们同时使用这两种方法 您可以使
  • GCM 向主题发送消息:TOO_MANY_TOPICS 错误

    以前 GCM 每个应用程序有 100 万个主题订阅的限制 我发现他们现在已经取消了这一限制 基于发布 订阅模型 主题消息支持 每个应用程序无限订阅 https developers google com cloud messaging to
  • Android 应用程序在后台运行时保存数据

    目前我正在开发 xmmp 客户端 当应用程序位于前台时 该客户端工作得很好 但由于事实上 当应用程序处于后台时 我在 Application 类中保存了大量数据 复杂的 ArrayList 字符串和布尔值作为公共静态 每个字段都被垃圾收集
  • 如何更新 Firebase 中的节点密钥?

    如何重命名14 04 2017 node 没有用于重命名节点的 API 您必须获取节点的值 使用新名称将其保存到数据库并删除旧节点
  • RxJava、Proguard 和 sun.misc.Unsafe

    我有以下问题RxJava 1 1 0 使用时Proguard 我没有更改 RxJava 版本或其 pro文件 但更新后OkHttp我无法编译使用Proguard因为我有关于sun misc Unsafe不在场 rxJava pro keep
  • 无法在自定义 AOSP 上安装 Google Play 中的某些应用程序:项目不可用。理由:9

    我在尝试从 Google Play 安装某些应用程序时收到以下错误 LibraryUtils isAvailable not available restriction 9 DocUtils getAvailabilityRestricti
  • 如果我们使用后退按钮退出,为什么 Android 应用程序会重新启动?

    按住主页按钮并返回应用程序时 应用程序不会重新启动 为什么使用后退按钮会重新启动 如果我们使用后退按钮退出 有什么方法可以解决在不重新启动的情况下获取应用程序的问题吗 请帮忙 当您按下Home按钮 应用程序将暂停并保存当前状态 最后应用程序
  • 线程自动利用多个CPU核心?

    假设我的应用程序运行 2 个线程 例如渲染线程和游戏更新线程 如果它在具有多核 CPU 当今典型 的移动设备上运行 我是否可以期望线程在可能的情况下自动分配给不同的核心 我知道底层操作系统内核 Android linux内核 决定调度 我的
  • 更新到材质 1.2.0 后,材质按钮上缺少圆角半径属性

    这是我的材质按钮代码
  • minHeight 有什么作用吗?

    在附图中 我希望按钮列与图像的高度相匹配 但我也希望按钮列有一个最小高度 它正确匹配图像的高度 但不遵守 minHeight 并且会使按钮向下滑动 我正在为按钮列设置这些属性
  • Android 启动器快捷方式

    我制作了一个简单的打卡 打卡时钟应用程序 我想向用户添加在主屏幕上创建快捷方式的选项 该快捷方式将切换应用程序的状态 超时 超时 但我根本不希望此快捷方式在屏幕上打开应用程序 这是我的 setupShortcut private void
  • 材质设计图标颜色

    应该是哪种颜色 暗 材质图标 在官方文档上 https www google com design spec style icons html icons system icons https www google com design s
  • 如何创建像谷歌位置历史记录一样的Android时间轴视图?

    我想设计像谷歌位置历史这样的用户界面 我必须为我正在使用的应用程序复制此 UIRecyclerView 每行都是水平的LinearLayout其中包含右侧的图标 线条和视图 该线是一个FrameLayout具有圆形背景和半透明圆圈Views
  • 通过 ADB 拔出设备:“找不到服务”

    我必须测试我的应用程序在打瞌睡模式下的行为 根据文档 https developer android com training monitoring device state doze standby html testing doze 我
  • 将 JSON 参数从 java 发布到 sinatra 服务

    我有一个 Android 应用程序发布到我的 sinatra 服务 早些时候 我无法读取 sinatra 服务上的参数 但是 在我将内容类型设置为 x www form urlencoded 之后 我能够看到参数 但不完全是我想要的 我在
  • SharedFlow 和 StateFlow 的主要区别

    两者有什么区别共享流 and 状态流 以及如何使用这些MVI建筑学 使用简单更好吗Flow或者这些作为状态和事件 Flow 是冷的 意味着它仅在收集数据时才发出数据 另外Flow不能保存数据 可以把它看成是水在里面流动的管道 Flow中的数
  • 用于推送通知的设备令牌

    我正在实施推送通知服务 我需要创建一个数据库来存储 4 个移动平台的所有设备令牌 我想根据他们的平台 iOS Android BlackBerry WP7 来组织它们 但是有什么方法可以区分平台 这样如果我只想向 Android 用户发送消
  • 在webview android中加载本地html文件

    我正在尝试在 android 的 webview 中加载 html 文件的内容 但是 它给了我 网页不可用错误 如果我尝试使用谷歌或雅虎等网站 它们就会起作用 html文件位于src gt main gt assests gt index
  • 找到 Android 浏览器中使用的 webkit 版本?

    有没有办法知道某些特定手机上的 Android 浏览器使用的是哪个版本的 webkit 软件 如果有一个您可以浏览以获取该信息的 URL 那就太好了 但任何其他方式也很好 如果你知道 webkit 版本 你就知道 html5 支持多少 至少
  • 在 Google 地图上绘制线条/路径

    我很长一段时间都在忙于寻找如何在 HelloMapView 中的地图上的两个 GPS 点之间画一条线 但没有运气 谁能告诉我该怎么做 假设我使用扩展 MapView 的 HelloMapView 我需要使用叠加层吗 如果是这样 我是否必须重

随机推荐

  • TIOBE 8 月编程语言:C、Java 差距拉大,R 语言盛行

    编程语言社区 TIOBE 最新发布了 8 月编程语言排行榜 相比上个月 本月 TIOBE 指数整个体变化并不大 C 语言依然保持强劲地增长势头 与第二名 Java 之间差距逐月增大 从上个月相差 1 35 的份额逐步增长到 2 55 的差额
  • 数据分析学习之路——(八)分类算法介绍

    前面几篇文章都是从数据分析介绍讲到描述统计分析 其实数据分析还需要使用机器学习的相关知识用来建立不同的分析模型 最终对数据信息进行深入的分析和挖掘 在实际工作当中 我们需要对数据进行特征分析 并且从数据中获取有价值的信息 并且为数据产品的市
  • 时不我待,拥抱趋势,开源IM项目OpenIM技术简介

    坚持开源 开源的理念是基于共享 合作和透明的原则 将软件 代码等知识资源公开并允许他人使用 修改和重新分发 以促进创新和发展 以下是几个开源的优点 创新 开源可以促进创新 通过让其他人改进或扩展已有的代码或项目 不断推动技术的进步 透明 开
  • C# TCP/IP网络数据传输及实现

    C TCP IP网络数据传输及实现 一 概念简述 1 什么是OSI 和TCP IP 2 什么是套接字Socket 3 TCP 和 UDP 4 IP MAC PORT 1 IP地址 2 MAC地址 3 Port端口号 二 UDP上位机的实现
  • 静态集合类

    如HashMap LinkedList等等 如果这些容器为静态的 那么它们的生命周期与程序一致 则容器中的对象在程序结束之前将不能被释放 从而造成内存泄漏 生命周期长的对象持有短生命周期对象的引用 尽管短生命周期的对象不再使用 但是因为长生
  • 服务器上部署scrapy爬虫项目

    爬爬们 如果你已经开始部署项目了 那么你肯定也已经写好了完整的爬虫项目 恭喜你 你很优秀 今天忙了小半天的服务器部署 跟大家分享一些心得 首先我们要有一台服务器 不好意思 这是废话 略过 安装python 下载安装包 好习惯可以自己创建文件
  • Acwing 897. 最长公共子序列

    f i j 表示所有在第一个序列的前i个字母中出现 且在第二个序列的前j个字母中出现的子序列中的最大个数 include
  • canvas在图片上做标记,可以单一也可以多个

  • docker 安装mongo数据库

    1 pull镜像 docker pull mongo 4 2 创建目录 mkdir p mongodb datadb chmod 777 mongodb datadb 3 运行 准备好目录之后 就可以开始运行 Docker 镜像了 dock
  • AI,v3,百度人脸识别库上传---node

    config有必要的grant type client id client secret var https require https var request require request var qs require querystr
  • The mbstring extension is missing. Please check your PHP configuration.

    在安装完毕wamp程序后 启动后访问phpmyadmin 出现错误 The mbstring extension is missing Please check your PHP configuration 解决方案 在php ini中修改
  • LRU算法的详细介绍与实现

    1 背景 LRU least recently used 最近最少使用算法 是一种内存数据淘汰策略 使用常见是当内存不足时 需要淘汰最近最少使用的数据 LRU常用语缓存系统的淘汰策略 2 LRU原理 LRU最早实在操作系统接触到这个算法的
  • Python Day6-元组-操作-拷贝

    Python元组 操作 拷贝 Python的元组与列表类似 不同之处在于元组的元素不能修改 元组中的元素也不能被删除 但可以删除整个元组 元组使用小括号 列表使用方括号 元组创建 只需要在括号中添加元素 并使用逗号隔开即可 1 元组的定义
  • 五人合伙最佳股份分配_老板要懂的股权合伙,懂股权者懂人心,合理分配得人心...

    1 合伙人股份分配协议分红 两人合伙 出钱不出力 出钱又出力 股份这样算 两人合伙开公司 A出资60万 不干活 B出资40万 全职无休 他们的股份该怎么计算 如果按资金占总股比例为60 人力占总股比例为40 来分配股权 A的资金股就是60万
  • Xmrig挖矿木马排查过程,xmrig占用大量CPU

    1 通过top发现xmrig占用了大量cpu 2 通过网上搜索发现是挖矿木马 3 尝试直接kill发现杀死之后又会自动重启 4 查找find name xmrig 文件 或者程序信息 ps aux grep xmrig 找到安装目录并将其删
  • Caffe:CPU模式下使用Intel MKL

    转自 https blog csdn net 10km article details 52724477 下载安装Intel MKL 打开这里Intel Math Kernel Library Intel MKL 点击 Get This L
  • MySQL索引机制(详细+原理+解析)

    MySQL索引机制 永远年轻 永远热泪盈眶 一 索引的类型与常见的操作 前缀索引 MySQL 前缀索引能有效减小索引文件的大小 提高索引的速度 但是前缀索引也有它的坏处 MySQL 不能在 ORDER BY 或 GROUP BY 中使用前缀
  • SDL教程零基础入门 简单操作 day1

    1 0 SDL 简介 文章目录 1 0 SDL 简介 1 1 什么是 SDL 1 2 SDL 可以做什么 2 在VS上获取和安装 SDL 2 1 SDL2库下载 2 2 安装SDL2 2 3 在Visual Studio中使用SDL 3 S
  • 浏览器播放rtsp视频流:2、ffmpeg转hls播放(go后端利用hls做简单视频直播)

    浏览器播放rtsp视频流 2 ffmpeg转hls播放 go后端利用hls做简单视频直播 文章目录 浏览器播放rtsp视频流 2 ffmpeg转hls播放 go后端利用hls做简单视频直播 1 前言 2 wsl安装ffmpeg并转换rtsp
  • Android性能优化之应用瘦身(APK瘦身)

    关于作者 CSDN内容合伙人 技术专家 从零开始做日活千万级APP 专注于分享各领域原创系列文章 擅长java后端 移动开发 人工智能等 希望大家多多支持 目录 一 导读 二 概览 2 1 apk组成 三 优化方向 3 1 源代码 3 1