电脑吃鸡优化设置
绝地求生是主打竞技的吃鸡游戏,玩家们进入对局之后,利用周围的建筑等来躲避其他玩家的追杀,十分刺激。恰逢4月12日绝地求生更新s23赛季,很多玩家的目光再次聚焦到这款游戏,玩家们想知道绝地求生画质如何调...
2024.11.20resources.arsc 这个文件在很多项目中都占用了相当多的空间。常见的优化方法是使用 AndResGuard 混淆减少文件名及目录长度,7z 压缩,如果有海外产品的话可以动态下发语言。 我们在做完这些优化后,由于公司内部有很多海外产品,涉及到多语言的关系,ARSC 依然很大,我们决定尝试进一步优化。经过调研,最终我们对 3 个方面做了优化,分别是删除无用 Name、合并字符串池中重复字符串、删除无用文案,最终带来的收益是 1.6MB。 在此之前,我们还在 AndResGuard 的基础上完成了重复 MD5 文件图片合并,原理是一样的。
8.2 原理先贴一张 arsc 结构的图,这个二进制文件的数据结构相当复杂,AndResGuard 其实只修改了这个文件的一小部分,至于更多的修改就无能为力了,于是我们自己解析了这个文件进行分析。 网上也有不少关于这个文件格式的说明,这里就不赘述了。推荐老罗和尼古拉斯的博客以及 aapt2 源码。google 提供的 android-arscblamer 和 apktool 的代码也值得一看。
下面用一张图简单描述一下修改过程:
如图,字符串其实是通过索引的方式来获取的,所有字符串都保存在两个字符串池中(单个 package),一个是全局字符串池,一个是 package 下的字符串池,我们只需要修改指向全局字符串的偏移值就行了。name 和 value 所在二进制位置如下图。
8.3 方案8.3.1 删除无用 NameAndResGuard 在今年的 7 月也增加了这个功能,我们来看一下实现原理。 Name 对应的字符串池是 package 字符串池,由于这个字符串池中只包含所有 Name,我们操作可以稍微暴力一点,先做一份备份,然后清空字符串池,添加一个用于替换的字符串,赋值为 [name_removed]。
首先要确定哪些 name 是通过 getIdentifier 调用,配置成白名单。 遍历 name 项,如果不在白名单,那么把这一个 name 的偏移替换成 0,使其指向[name_removed]。 如果 name 在白名单,那么不应该删除,我们通过备份的字符串池找到这个 name 对应的字符串,添加到字符串池中,把偏移指向对应下标即可。
抖音通过这个优化减少了包大小 70k。
8.3.2 合并重复字符串value 所对应的是全局字符串池,虽然名字听起来不会有重复值,但在我们扫描排序后发现其实有很多重复字符串(用 AppBundle 打包就不会存在这个问题) 在抖音项目中,这个字符串池里有 1k+个重复字符串,合并这些字符串是非常必要的。
我们先遍历所有数据,然后把字符串池的重复字符串合并,记录偏移的修改,最后把需要修改的 value 的引用指向新的偏移。这个过程需要操作 arsc 数据结构的 ResValuel 和 ResTableMap,以保证所有 string 类型的值都能得到替换。
抖音通过这个优化减少了包大小 30k。
8.3.3 删除无用文案在打包过程中,其实所有 strings.xml 中保存的字符串都是不会被优化的,随着项目逐渐变大,一些废弃文案或者下个版本才有用的文案被引入了 apk 中,我们在 Proguard 后再次扫描,发现了 3000+个无用字符串。在公司内部的一些海外项目中,有的文案被翻译成 100 多个国家的语言,占用了极大的空间。
删除的方法和上面类似,都是指向替换的字符串所在偏移。 如图可能会存在两个不同 name 指向同一个字符串,需要判断待删除的字符串是否还有其他引用。
不同项目收益可能不太一样,公司内部海外项目对这些无用文案进行了替换,减少了 1.5M 包大小左右。
8.4 实现如果是普通的 assemble 打包,直接在 ProcessResources 过程中获取 ap_文件中的 arsc 文件,利用我们的工具修改即可。
如果是 AppBundle 方式打包,修改 ap_是没有用的,因为最后产物是用 aapt 以 proto 格式生成的 resources.pb 文件,要修改只能 hook aapt 过程。这个文件和 arsc 文件结构不太一样,好在我们可以使用官方提供的 Resources 类解析、生成 pb 文件,使用相似的方法修改即可。
修改效果如图:
8.5 进一步优化arsc 中的偏移数组是有优化空间的,我们会在未来尝试进行优化。 用二进制编辑器打开 arsc 文件可以发现,这样的 FF 值在文件中大量存在。
是什么导致了这样的空间浪费? 我们可以看到下图中框选的空白,每一个都代表了其字符串所在的偏移值,这里并没有值,赋值 FF FF FF FF 作为默认偏移值,浪费了 4 字节空间。 某些列(configuration)可能就只有几个格子有值,如图抖音中 drawable 有 4k+张图片,有 24 列,大多数 configuration 只有几张图片,因此浪费了 4k*23*4380k。大致估算,抖音可以减少 1M 体积。(压缩前)
如下图 facebook 针对 arsc 文件的处理,我们可以把一行只有一个值的 id 抽出来,单独放到一个 Resource Type 中,每一个 id 只有一个值,避免了上述空间浪费情况。 但这样做修改了 ID,因此对应的代码中的 ID 也要修改,涉及了逆向 xml 以及 dex,提高了修改成本。还有一种思路是修改 aapt 源码,没有直接改 arsc 灵活。
9.总结上述就是我们抖音 Android 端在包大小优化方面针对资源做的一些尝试和积累,力求追求极致。
我们针对包大小优化,在其他方面还做了很多优化措施:针对 so 优化,做了 so 合并、stl 版本统一、精简导出符号表和 so 压缩等措施;针对代码优化,细化混淆规则,开发 bytex 插件进行无用代码扫描、acess 方法内联、getter/setter 方法内联、删除行号等优化措施。
除了优化措施,良好的包大小监控系统是防止包大小劣化最重要的工具,否则包大小优化措施取得的收益抵不过业务快速迭代带来的包大小增长。抖音 Android 端结合 CI、Cony 平台,开发出了一套代码合入前置检查系统,每个分支增量超过阈值不准合入;还开发了分业务线监控包大小的工具,便于监控每个业务线包大小增长和给各个业务线定包大小指标。
最后,抖音 Android 诚招对技术有无限热情的小伙伴。感兴趣的小伙伴都可以通过 字节跳动招聘官网查询抖音 Android 相关职位() 或简历发送至 shipeiqing@bytedance.com。
更多分享欢迎关注字节跳动技术团队
绝地求生是主打竞技的吃鸡游戏,玩家们进入对局之后,利用周围的建筑等来躲避其他玩家的追杀,十分刺激。恰逢4月12日绝地求生更新s23赛季,很多玩家的目光再次聚焦到这款游戏,玩家们想知道绝地求生画质如何调...
2024.11.20抖音店是抖音短视频营销流量实现的电子商务工具,是抖音为短视频我们媒体作者提供内容实现的渠道。抖音店开业后,抖音卖家可以在头条新闻、抖音和火山个人主页上显示自己的专属店铺页面。然后,让我们来看看抖音店的...
2024.11.22抖音是现在人气最高的一个短视频网站,它的用户数量很多,很多自媒体人都会选择用它来做广告。但是,如果你没有知名度,就很难做好。所以,想要增加用户的关注度,就必须要提升自己的人气。下面,小易带大家学习一下...
2023.02.08抖音去水印解析网站、软件、小工具有很多,但是一搜索几乎都需要收费才可以去水印使用。果断恼怒!!!那有没有一种能免费去水印的小工具呢?网上五花八门的工具很多,但是随着短视频平台的更新,很多工具并不稳定,...
2024.11.22抖音直播没人气怎么办?抖音直播怎么增加人气?做抖音主播怎么上热门主播?小卓老师之前遇到过很多新人主播,他们在直播的时候,直播间的人很少,留不住人,他们常常会问我改怎么办?本期小卓老师就来告诉给大家分享...
2023.02.08