写点什么

开源 | 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:061588

评论

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

架构师训练营第十二周总结

张明森

30年技术积累,技术流RTC如何成为视频直播领域的黑马?

华为云开发者联盟

云计算 AI 5G RTC 华为云

大事情!中国限制 AI 算法出口。网友:这是要阻止XX“下跪”

程序员生活志

SpringBoot+Tess4j实现牛逼的OCR识别工具

小隐乐乐

LeetCode 5. Longest Palindromic Substring

liu_liu

算法 LeetCode

翻转链表算法、自动化测试框架robot-framework、两款iOS 在手机端debugging 工具Flex、啄木鸟、加密技术 高可用系统的度量 高可用系统的架构 高可用系统的运维 John 易筋 ARTS 打卡 Week 15

John(易筋)

ARTS 打卡计划 高可用系统的架构 翻转链表 自动化测试Robot 手机调试工具Flex

麦叔告诉你,Linux下安装nginx都踩了那些坑

麦洛

nginx Linux

【读书笔记一】《企业IT架构转型之道-阿里巴巴中台战略思想与架构实战》

Man

中台 阿里 中台战略

软件产品的创新与宇宙奇点大爆炸

常平

方法论 产品思维 架构思维

程序的机器级表示-控制

引花眠

计算机基础

基于区块链的社会治理探索

CECBC

区块链 大数据 信息技术

你真的懂 Java 的 main 方法吗

Rayjun

Java

pandas ~基础pandas

南辞

Python

央行数字货币钱包上线后又秒关 兑换了的 DCEP 别担心

CECBC

数字货币 央行

图解Node(上)——直击灵魂的十条拷问

执鸢者

大前端 原理 Node

ARTS Week14

时之虫

ARTS 打卡计划

架构师训练营第十二周作业

张明森

小小的分页引发的加班血案

架构师修行之路

架构

雪花算法把玩

ElvinYang

oeasy教您玩转linux010109clear清屏

o

比特币挖矿到底挖的是什么?

CECBC

比特币 区块链 数字货币

Ray 分布式计算框架详解

lipi

分布式 数据湖 pandas Apache Arrow

k8s-client-go源码剖析(二)

远鹏

Kubernetes 源码剖析 Go 语言

oeasy教您玩转linux010108到底哪个which

o

面经手册 · 第8篇《LinkedList插入速度比ArrayList快?你确定吗?》

小傅哥

Java 数据结构 面试 小傅哥 linkedlist

【持续更新~】常遗忘却可以变更好的心态

01Running

个人成长

ARTS打卡 第14周

引花眠

微服务 ARTS 打卡计划

JVM的早期优化与晚期优化

Edison

JVM JVM虚拟机原理

高并发系统三大利器之降级

root

Flink检查点、保存点及状态恢复-13

小知识点

scala 大数据 flink

架构师第十二周学习总结

傻傻的帅

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