本文来自网易云社区

作者:郑文

首先我们并不在讨论车牌号.本文尽量避免谈论重复的技术点,只探讨一下multidex提供给我们的技术启示。

原理

multidex技术原理可以分成两个部分:

  • 在app启动时,通过Multidex.install api,扩展ClassLoader的dexElements数组来存储所有dex,这个流程会根据android sdk版本的不同做不同的处理,整个流程完全通过反射完成。

  • 编译过程中的分包机制,将app中的class以某种方式将class分布在多个dex中

Multidex.install

从multidex的原理,很容易想起目前比较流行的一个代码热修复方案策略。安卓App热补丁动态修复技术介绍,qzone的技术思路在社区诞生了很多技术框架,其中知名度最高的就是Nuwa。但客观的说,nuwa这个项目是完全达不到产品release的要求。在调研完所有同技术路线开源框架后,我们决定造个能应用在线上产品的轮子。

我们的解决方案

  • 使用Transform API进行bytecode的植入,支持高版本gradle

  • 编译流程的优化,减少了人工干预的过程

  • 支持补丁包的签名验证,避免被恶意hook

  • 兼容网易安全部门的加壳方案

  • 支持ART模式:在art模式下,应用补丁包可能导致地址错乱,解决方案是将直接引用修改class的相关类都打包进行补丁包,这是目前其他开源方案没有做的

MultiDex存在的问题

MultiDex机制的出现本身是为了避免出现app 65535问题的出现,但随着业务逻辑的增长,以及不合理的模块划分,导致main dex的方法数也超出了65535,这就导致了main dex capacity exceeded异常。

同时,Multidex的接入额外还会对app的启动性能造成影响。Multidex在install时需要加载dex,首次启动时还需要做odex的转换,而这些都是在ui主线程中完成。 根据Carlos Sessa的测试,启用multidex后,4.4或以下的设备,app的启动时间平均会增加15%的时间,更严重的情况,甚至在启动时候会出现了黑屏。

目前部分app采取的策略是,放弃掉Multidex的,而转为插件化的架构。通过将非核心模块的lazy load,来达到启动速度的优化,但我们需要明确的是,并不是所有app都似乎插件化架构,为了实现启动加速或热更新将本耦合的业务逻辑硬生生拆解才是本末倒置。

解决方案

Multidex异步化

在Android的性能优化中,最常见的思路就是异步化,减少UI线程的工作。在应用的交互层面上,app启动时,几乎所有app都会有一个SplashActivity。在界面上展示欢迎页,在后台进行初始化的业务逻辑。这就给我们一个启发,我们可以将系统的初始化逻辑,延迟到我们的业务初始化时间点上。

更加具体的方式是,我们可以将Multidex.install异步化,保证主线程的正常进行,待加载完成后通知SplashActivity跳转到真正的业务主界面。

在MultiDex加载的异步化之后,我们可以进行第二步:main dex大小的精简。

Multidex分包原理介绍

Multidex会在入口Application的attachBaseContext,加载second dex,因此multidex分包的基本原则是:保证app启动需要的class放置在main dex上。在gradle 1.5以上,multidex通过CreateManifestKeepList和MutidexTransform完成,分包过程可以分为三步:

  • 生成manifest_keep.txt

CreateManifestKeepList会解析出AndroidManifest.xml中所有的组件类:包括Activity、Service、Receiver以及ContentProvider,这些类将会和Application入口类一起放在build/intermediates/multi-dex/{flavor}/{buildType}/manifest_keep.txt中

  • 生成maindexlist.txt文件

MutidexTransform会查找manifest_keep.txt中所有类的直接引用类,具体的方式是遍历类的所有字段类以及方法,查看方法的参数和返回值的类型,将其放保存在maindexlist.txt

  • 生成main dex

相关文章:
【推荐】 一份ECMAScript2015的代码规范(下)

当我们在谈论multidex65535时,我们在谈论什么的更多相关文章

  1. 当我们谈论CloudTable时究竟在谈论什么?

    表格存储服务(CloudTable Service,简称CloudTable)是基于Apache HBase提供的分布式.可伸缩.全托管的毫秒级NoSQL数据存储服务.它提供了毫秒级的随机读写能力,适 ...

  2. 当我们在谈论 DevOps,我们在谈论什么?

    Cloud Insight 携手 BearyChat:打造适合运维人员的团队协作工具 走过 C 轮的 OneAPM,旗下的产品已经日渐丰满,从应用性能监控的 Application Insight 到 ...

  3. MySQL Bug剖析之Slave节点并行复制死锁

    此文已由作者温正湖授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 有天一早,DBA同学就找上来了,说有个DDB集群下的RDS实例Slave节点(从库)死锁了,请求支援.说实话 ...

  4. C/C++中数组与指针的关系探究

    数组与指针 长期以来,在C/C++中,数组名和指向数组首元素的指针常量到底是以一种什么关系,一直困扰着很多人.很多地方,甚至是一些教科书中都在说,"数组名就是一个指向数组首元素的指针常量&q ...

  5. 以虎嗅网4W+文章的文本挖掘为例,展现数据分析的一整套流程

    本文转自知乎 作者:苏格兰折耳喵 ----------------------------------------------------- 本文作者将结合自身经验,并以实际案例的形式进行呈现,涉及从 ...

  6. Facebook内部报告:争取青少年用户的鸡贼小技巧

    翻译:吴祺深 欢迎访问网易云社区,了解更多网易技术产品运营经验. 去年十月,Facebook收购了TBH,最后却关闭了这款APP,不过一则内部报告透露了,通过这款流行的投票APP,这家公司学会了如何去 ...

  7. DevOps 工程师成长日记系列三:版本

    原文地址:https://medium.com/@devfire/how-to-become-a-devops-engineer-in-six-months-or-less-part-3-versio ...

  8. OAuth 2.0、OIDC 原理

    OAuth 目录 OAuth 什么是 OAuth? 为什么是 OAuth? SAML OAuth 和 API OAuth 主要组件 OAuth 作用域 OAuth 参与者 OAuth 令牌 OAuth ...

  9. [Erlang 0116] 当我们谈论Erlang Maps时,我们谈论什么 Part 1

         Erlang 增加 Maps数据类型并不是很突然,因为这个提议已经进行了2~3年之久,只不过Joe Armstrong老爷子最近一篇文章Big changes to Erlang掀起不小了风 ...

随机推荐

  1. MVC框架介绍

    第一,建立一个解决方案然后在该解决方案下面新建mvc空项目. 第二,下面先对该项目的一些文件进行介绍: MVC项目文件夹说明: 1.(App_Data):用来保存数据文件,比如XML文件等 2.(Ap ...

  2. C# user32.dll

    #region User32.dll 函数 /// <summary> /// 该函数检索一指定窗口的客户区域或整个屏幕的显示设备上下文环境的句柄,以后可以在GDI函数中使用该句柄来在设备 ...

  3. 实战zabbix3.0.2 使用percona mysql插件监控mysql5.7

    1.系统环境 [root@shard0 templates]# cat /etc/redhat-release Red Hat Enterprise Linux Server release 7.2 ...

  4. numpy中的ndarray方法和属性

    原文地址 NumPy数组的维数称为秩(rank),一维数组的秩为1,二维数组的秩为2,以此类推.在NumPy中,每一个线性的数组称为是一个轴(axes),秩其实是描述轴的数量.比如说,二维数组相当于是 ...

  5. proxmox 去除订阅提示

    去掉登陆时是否订阅通知修改文件   /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js 搜索关键字  “You do not have ...

  6. 如何在eclipse中添加android ADT(转)

    转自: http://jingyan.baidu.com/article/b0b63dbfa9e0a74a4830701e.html 对于程序开发的学者来说,eclipse并不陌生,它为我们提供了一个 ...

  7. jQuery学习之jQuery Ajax用法详解(转)

    jQuery Ajax在web应用开发中很常用,它主要包括有ajax,get,post,load,getscript等等这几种常用无刷新操作方法,下面我来给各位同学介绍介绍. 我们先从最简单的方法看起 ...

  8. Inception

    http://baijiahao.baidu.com/s?id=1601882944953788623&wfr=spider&for=pc

  9. 可跨平台C++开源图形图像框架:openFrameworks

    博客参考:https://www.hahack.com/codes/openframeworks-intro/#%E4%BB%80%E4%B9%88%E6%98%AF-openframeworks 和 ...

  10. Linux automake命令

    1)automake 使用教程 http://loftor.com/archives/automake.html 2)configure.in Makefile.am解析 http://blog.cs ...