关于android:基于APK加速启动时间的Android系统资源优化

42次阅读

共计 2933 个字符,预计需要花费 8 分钟才能阅读完成。

为了尽可能减⼩应⽤的⼤⼩,咱们应该在公布版本中移除不使⽤的代码和资源。另外还存在两个 优化⽅向能够⽤来缩减应⽤程序的占⽤空间,⼀项是使⽤混同解决性能,该性能会缩短应⽤的类 和成员的名称;另⼀项是使⽤优化性能,该性能会采⽤更踊跃的策略来进⼀步减⼩应⽤的⼤⼩。本⽂将介绍如何通过 APK 的资源优化来加重应⽤程序的占⽤空间从⽽节俭⽤户资源。

提出问题

⾸先使⽤友盟 + 推出的产品 U -APM 来理论测试应⽤程序在不同的设施上的使⽤状况:

从图中能够看出应⽤程序在启动工夫上还存在优化空间,下⼀步咱们将读取应⽤程序的内存分 配,确定能从哪些⽅向⼊⼿对资源进⾏优化,从⽽放慢启动工夫。

为了对以上⼏个指标进⾏详细分析,咱们使⽤了 Android 窗⼝上的 Memory 选项卡,它将向我 们显示随工夫在堆上调配的数据量:

图中显示发⽣了 GC 事件,删除了未使⽤的对象并开释了堆上的空间。

为了考察以后在堆中调配的内容,咱们能够使⽤左侧的堆转储按钮。这将对堆中以后调配的内容 进⾏快照,并将其显示在 Android Studio 内的非凡报告屏幕中:

在左侧,咱们看到堆中实例的直⽅图,按类名分组。对于每⼀个,都有调配的对象数量、这些实 例的⼤⼩(浅层⼤⼩)以及这些对象在内存中保留的⼤⼩。后者通知咱们如果这些实例被开释,能够开释多少内存。这个视图让咱们对应⽤程序的内存占⽤有⼀个重要的理解,帮忙咱们辨认⼤ 型数据结构和对象关系。这些信息能够帮忙咱们构建更⾼效的数据结构,解开对象连接以缩小保 留的资源,并最终尽可能地缩小资源占⽤。

随后,咱们使⽤单个布局⽂件构建⼀个最⼩的 APK,以计算布局⽂件的名称在 Android APK 中 呈现次数。

使⽤ Gradle 构建 Android 应⽤程序只须要⼀个 AndroidManifest.xml ⽂件。咱们能够增加⼀个 虚构布局。

运⾏ gradle assembleRelease 将产⽣⼀个只有 2, 118 字节的公布版 APK。咱们能够使⽤转储其 内容 xxd 并查找 home_view 字节序列。

依据此输入,在 APK 中存在 3 次未压缩的门路和 1 次未压缩的仅名称。

zip ⽂件是⼀个⽂件条⽬列表,后跟所有可⽤条⽬的⽬录。每个条⽬都蕴含⽂件门路,⽬录也是 如此。这阐明了输入中的第⼀次呈现(条⽬题目)和最初⼀次呈现(⽬录记录)。

输入中呈现的两头两次来⾃ resources.arsc ⽂件外部,该⽂件是资源排序的数据库。它的内容是 可⻅的,因为该⽂件在 APK 中未压缩。运⾏ aapt dump –values resources

build/outputs/apk/release/app-release-unsigned.apk 显示 home_view 记录及其到门路的映 射:

APK 蕴含 classes.dex ⽂件中第五次呈现的名称。它没有显示在 xxd 输入中,因为⽂件被压缩 了。运⾏ baksmali dump <(unzip -p build/outputs/apk/release/app-release-unsigned.apk classes.dex) 显示 dex ⽂件的字符串表,其中蕴含以下条⽬

home_view:

这是⽤于将 R.layout 布局名称映射到唯⼀整数值的类中的字段。顺便说⼀下,该整数是

resources.arsc 数据库的索引,⽤于查找相干⽂件名以读取其 XML 内容。

总结⼀下咱们问题的答案,对于每个资源⽂件,残缺门路呈现 3 次,名称呈现两次。

优化资源

Android Gradle 插件 4.2 引⼊了⼀个 android.enable ResourceOptimizations=true 标记,它将 运⾏针对资源的优化。这会 aapt optimize 在合并的资源和 resources.arsc ⽂件打包到 APK 之前 调⽤它们的命令。优化仅适⽤于公布版本,⽆论是否 minifyEnabled 设置为 true,都会运⾏。增加标记后,gradle.properties 咱们能够使⽤漫反射来⽐较两个 APK 以查看其成果。输入很 ⻓,所以咱们将按局部合成。

⾸先是 APK 中内容的差别。“压缩”列是 APK 内的老本,“未压缩”列是提取时的老本。

该 res 类别代表咱们的单个资源⽂件,其⼤⼩降落了 28 个字节。该 arsc 类别⽤于 resource.arsc 自身,显然,这⾥产⽣了⼀定的优化。

这两局部代表资源数据库的代码和内容。没有变动,咱们能够推断优化没有影响

R.layout.home_view 字段和 home_view 资源条⽬。

最初显示了优化的成果。咱们的布局资源的⽂件名被显著截断并移出 layout/ ⽂件夹。

在 Gradle 项⽬中,XML 的⽂件夹和⽂件名是有意义的。⽂件夹是资源类型,名称对应.arsc ⽂ 件中⽣成的字段和资源条⽬。然而,如果这些⽂件位于 APK 中,⽂件门路就变得毫⽆意义。资 源优化通过使名称尽可能短来进⾏优化。

输入 aapt dump 资源数据库也反映了⽂件更改:

APK 中门路的所有三个呈现当初都更短,从⽽节俭了 36 字节。尽管 36 字节是⼀个⾮常⼩的 数字,但整个⼆进制⽂件只有 2, 118 字节。36 字节的节俭了 1.7% 的资源。

Nick Butcher 的 Plaid 应⽤程序有 734 个资源⽂件。除了数量之外,资源⽂件的名称更具形容 性(这是说它们更⻓的⼀种奇异⽅式)。home_viewPlaid 蕴含的名称是 searchback_stem_search_to_back.xml、attrs_elastic_drag_dismiss_frame_layout、和 designer_news_story_description.xml。

没有资源优化的构建与启⽤它的构建进⾏⽐较:

资源优化使 APK ⼤⼩节俭了 0.76%。

Uwe Trottmann 的 SeriesGuide 应⽤程序有 1044 个资源⽂件。与 Plaid 不同,它没有本机

库,这应该会让优化成果更好。

我再次将项⽬更新到 AGP 4.2 并⽐较两个版本:

在这⾥,资源优化可能将 APK ⼤⼩缩小 2.0%!

Chris Banes 的 Tivi 应⽤程序有⼀个使⽤ Jetpack Compose 编写的重要⼦集,这意味着整体资 源更少。以后构建仍蕴含 776 个资源⽂件。

通过使⽤ Compose,Tivi 曾经在使⽤最新的 AGP 4.2。通过两个疾速构建,咱们能够看到资源 优化的影响:

咱们再⼀次达到了 APK ⼤⼩缩减 2.0% 的水平

APK 签名

APK 签名有多个版本,如果您的版本 minSdkVersion 低于 24,则须要在签名时蕴含版本 V1。V1 签名使⽤ Java 的.jar 签名标准,该标准将每个⽂件作为⽂件中的⽂本条⽬独自签名 META-

INF/MANIFEST.MF。

在为原始单布局应⽤程序创立和配置密钥库后,转储清单⽂件 unzip -c

build/outputs/apk/release/app-release.apk META-INF/MANIFEST.MF 显示以下签名:

![](/img/bVcVZO2)

每个⽂件的残缺门路呈现,使每个资源门路的总呈现次数达到四次。因为较短的名称将再次导致 此⽂件蕴含更少的字节,因而资源优化在签名中具备更⼤的影响。

__

依据材料显示,这⼀⽅法能够节俭 1-3% 的 APK ⼤⼩。依据理论测试,这个范畴仿佛是正确

的。最终节俭的费⽤将取决于 APK 中资源⽂件的⼤⼩和数量。

正文完
 0