写点什么

开源 | BoostMultiDex:挽救 Android Dalvik 机型 APP 升级安装体验

  • 2020-06-01
  • 本文字数:2421 字

    阅读完需:约 8 分钟

开源 | BoostMultiDex:挽救 Android Dalvik 机型APP升级安装体验

现代 Android APP 的代码量通常都比较大,很容易就会带上多个 DEX 文件。Android 低版本的设备采用的 Java 运行环境是 Dalvik 虚拟机,如果含有多个 DEX 想要在这些设备上正常运行,就需要使用官方的 MultiDex 方案。MultiDex 需要对 APK 内的原始 DEX 文件做 ODEX 优化,所以执行时间过于漫长,这就会使得安装或者升级后首次 MultiDex 花费的时间很久。


抖音自研的 BoostMultiDex 方案,可以大幅改善原有的 MultiDex 耗时。并且,不同于目前业界所有优化方案,我们是从 Android Dalvik 虚拟机底层机制入手,从根本上解决了安装后首次执行 MultiDex 耗时过长问题。


之前已经发布过两篇文章,详细介绍了 BoostMultiDex 的实现原理:


抖音 BoostMultiDex 优化实践:Android 低版本上 APP 首次启动时间减少 80%(一)


抖音 BoostMultiDex 优化实践:Android 低版本上 APP 首次启动时间减少 80%(二)


其中也展示了这一优化带来的显著效果:


开源地址


Github 项目地址:


https://github.com/bytedance/BoostMultiDex

实际表现

我们之前的文章里面只是提到了技术分析和一些优化数据,为了让大家更加直观地感受 BoostMultiDex 带来的明显效果,这里就来看下我们项目中实际表现是怎样的,以今日头条 APP 为例,左边是 BoostMultiDex,右边是原始 MultiDex:


https://mp.weixin.qq.com/mp/readtemplate?t=pages/video_player_tmpl&auto=0&vid=wxv_1355562813275815937


可以明显看到页面打开时间的差距,左边的 BoostMultiDex 方案有非常显著的优化,界面在短暂等待后就立即展示出来了,而右边的原始 MultiDex 方案要等待半分钟左右才能展示界面。


当然,这个优化带来的实际体验提升情况,还要看结合每个 APP 自身。除了加载多 DEX 的时间,APP 启动阶段还有大量自身业务逻辑,而这块的耗时是相对固定的。这属于业务层面的启动优化问题了,应当尽量减少启动阶段执行那些不会立即使用的模块加载。 而 BoostMultiDex 的接入成本极低,能保证仅替换一行代码,就达到立竿见影的效果。

快速接入

本方案的使用和官方 MultiDex 基本上是一致的,只需两步即可接入。


首先,在 build.gradle 的 dependencies 中添加依赖:


dependencies {... ...    implementation 'com.bytedance.boost_multidex:boost_multidex:${ARTIFACT_VERSION}'}
复制代码


然后,与官方 MultiDex 类似,在 Application.attachBaseContext 的最前面进行初始化:


public class YourApplication extends Application {
@Override protected void attachBaseContext(Context base) { super.attachBaseContext(base);
BoostMultiDex.install(base);
... ... }
复制代码


这样就完成了所有工作了。立马编译运行,看看是不是 APP 首次冷启动变得健步如飞?

一些补充

之前的两篇文章中已经对 BoostMultiDex 方案的技术实现细节有详细叙述,主要涵盖了以下几个


技术要点:


  1. 利用系统隐藏函数,直接加载原始 DEX 字节码,避免 ODEX 耗时

  2. 多级加载,在 DEX 字节码、DEX 文件、ODEX 文件中选取最合适的产物启动 APP

  3. 单独进程做 OPT,并实现合理的中断及恢复机制


此外,这里再补充一些说明。

主 DEX 相关

首先,和 MultiDex 一样,BoostMultiDex 的所有类都是需要打入主 DEX 里面的,默认情况下,由于 Application 内有直接引用 BoostMuliDex,Gradle 就会自己帮我们自动打入主 DEX。但如果由于某些罕见的异常情况没有打入,我们就需要自己额外做这个处理,强制把com.bytedance.boost_multidex包中的所有类打入到主 DEX 里。

对于 ODEX 优化进程的处理

ODEX 优化进程是在名为:boost_multidex的进程中的,他会开启一个OptimizeService后台服务做优化,当然,所有进程都会走到Application里,Application里包含了很多其他进程共有逻辑,对于 ODEX 优化进程而言,这些逻辑是不需要的,因此,我们提供了一个BoostMultiDex.isOptimizeProcess方法,便于使用者自行判断,直接跳过这些无关业务逻辑。由于整个 BoostMultiDex 都在主 DEX 中,因此对于 ODEX 优化进程,BoostMultiDex.install也是不需要的。当然不做这个判断也关系不大,只是会额外执行一些无用代码,有些许效率损失。

Android 4.4 的 ART 机型

Android 4.4 机型同时集成了 Dalvik 和 ART 两套虚拟机,一般厂商的默认出厂机型都是采用 Dalvik 的。由于本方案只针对 Android Dalvik 机型有优化,对 ART 是没有效果的,因此,如果遇到某个机型优化效果差异不大,可以先看下是什么机型,并从输出日志可以看出是什么原因没有走到优化逻辑。

部分 Dalvik 内部数据结构有偏移的机型

我们的方案中涉及到对 Dalvik 虚拟机内部DvmDex结构体做设置,而如果厂商对这些结构做了特殊修改,就会导致设置到错误的偏移。这种情况目前看来还是极少的,仅在我们在线上大面积灰度过程中发现了一些 HTC 机型有修改这个结构,对此我们已经做了修正。这里也提前说明,避免大家在看到这块代码的时候遇到困惑。

最后

当然,技术上说的再多,不如看实际收益。目前,BoostMultiDex 已经在抖音亿级全球用户上验证通过,可以说涵盖了各种复杂情况的 Android 机型,目前业界其他大型 APP 都很难涉及到如此广泛的规模。由此,我们也解决了各种奇怪的兼容性问题,最大程度上确保了技术方案的稳定性。


对于项目的开源代码,我们保证, 和抖音自身使用的代码完全一致 ,直接开箱即用,避免大家接入后还要自己踩一遍我们曾经遇到的坑。如果在实际使用过程中如果遇到什么问题,我们也希望大家及时提出,一起贡献代码,共同将 BoostMultiDex 打造得更加稳健高效。


目前, 抖音 Android 基础技术团队仍在上海、北京、杭州、深圳大力招人 ,如果你也同样对技术充满热情,同样追求极致优化,想要与我们共同建设亿级用户全球化 APP,那就欢迎进入字节跳动招聘官网查询抖音 Android 相关职位,也可以联系 xiaolin.gan@bytedance.com 咨询相关信息或者直接发送简历内推!


本文转载自公众号字节跳动技术团队(ID:toutiaotechblog)。


原文链接


https://mp.weixin.qq.com/s/0gtkc7IQdhKjFxrHCuNZwQ


2020-06-01 10:061548

评论

发布
暂无评论
发现更多内容

是什么Java面试题PDF被Git全面封杀?刷完这套题已经拿完9个Offer!

Java 程序员 后端

最新基准测试:Kafka、Pulsar-和-RabbitMQ-哪个最快,阿里Java笔试题目

Java 程序员 后端

最近被安排搞搜索接口优化,压测了4次,才勉强达到要求

Java 程序员 后端

服了!阿里资深架构师发布SpringCloud笔记,在GitHub标星已达81

Java 程序员 后端

本科毕业斩获字节offer的我做了什么准备?大厂面试经验试题分享(1)

Java 程序员 后端

来自北京大学NOIP金牌选手yxc的常用代码模板3——搜索与图论

Java 程序员 后端

斯坦福高效睡眠法-读书笔记,这可能是目前最全的

Java 程序员 后端

新人问一般都用哪些 Linux 命令,我把这个扔了过去,linux基础及应用教程课后答案

Java 程序员 后端

普通程序员就不能有拥有架构师光环?想要建立架构思维,这份京东架构技术精髓一定不能错过

Java 程序员 后端

本科毕业斩获字节offer的我做了什么准备?大厂面试经验试题分享

Java 程序员 后端

数据库ACID四大特性到底为了啥,一文带你看通透,java支付宝支付接口教程

Java 程序员 后端

数据库索引的原理,springcloud视频百度云

Java 程序员 后端

数据结构的栈和队列(这不进来看一看),计算机java语言入门

Java 程序员 后端

推荐一款技术人必备的接口测试神器:Apifox,不愧是大佬

Java 程序员 后端

数据结构系列第六部分:排序,Github爆火的《高并发秒杀顶级教程》

Java 程序员 后端

排除MySQL中常见错误的实用招术,什么是微服务扩展性和高可用、可扩展性

Java 程序员 后端

无论你是什么职业,这篇职场生存法则都是你必备的,java微服务架构技术

Java 程序员 后端

有个厉害的程序员老婆是什么体验?,mysql性能优化面试题

Java 程序员 后端

数据库中间件MyCat实战笔记(第一步),arm架构linux系统

Java 程序员 后端

拜读!程序员60K+高薪技术,spring整合mybatis原理

Java 程序员 后端

拿捏了!ConcurrentHashMap!,宝塔linux建站教程

Java 程序员 后端

提升开发效率N倍的20+命令行神器,赶紧收藏了,mybatis原理图

Java 程序员 后端

月薪60k的Java开发在阿里是什么级别?对技术能力有哪些要求?

Java 程序员 后端

推荐这款牛掰的 API 敏捷开发工具,java程序设计教程课后题答案

Java 程序员 后端

数据源的概念是什么?Springcloud+Mybatis如何使用多数据源

Java 程序员 后端

普通本科,毕业六年,复盘一个月,mybatis一级缓存和二级缓存面试题

Java 程序员 后端

最新版SpringBoot开发实战:阿里技术官从基础到项目综合实战pdf

Java 程序员 后端

如何用内网渗透突破安全策略

网络安全学海

网络安全 信息安全 渗透测试 WEB安全 安全漏洞

拼多多3面+余额宝4面+蚂蚁金服5面,Java自学宝典

Java 程序员 后端

数论 - 约数基础 【 试除法求所有约数 + 约数个数和约数之和

Java 程序员 后端

是什么让普通的链表也能达到二分查找的效率,你知道吗?

Java 程序员 后端

开源 | BoostMultiDex:挽救 Android Dalvik 机型APP升级安装体验_开源_字节跳动技术团队_InfoQ精选文章