当我们在谈论multidex65535时,我们在谈论什么
本文来自网易云社区
作者:郑文
首先我们并不在讨论车牌号.本文尽量避免谈论重复的技术点,只探讨一下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时,我们在谈论什么的更多相关文章
- 当我们谈论CloudTable时究竟在谈论什么?
表格存储服务(CloudTable Service,简称CloudTable)是基于Apache HBase提供的分布式.可伸缩.全托管的毫秒级NoSQL数据存储服务.它提供了毫秒级的随机读写能力,适 ...
- 当我们在谈论 DevOps,我们在谈论什么?
Cloud Insight 携手 BearyChat:打造适合运维人员的团队协作工具 走过 C 轮的 OneAPM,旗下的产品已经日渐丰满,从应用性能监控的 Application Insight 到 ...
- MySQL Bug剖析之Slave节点并行复制死锁
此文已由作者温正湖授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 有天一早,DBA同学就找上来了,说有个DDB集群下的RDS实例Slave节点(从库)死锁了,请求支援.说实话 ...
- C/C++中数组与指针的关系探究
数组与指针 长期以来,在C/C++中,数组名和指向数组首元素的指针常量到底是以一种什么关系,一直困扰着很多人.很多地方,甚至是一些教科书中都在说,"数组名就是一个指向数组首元素的指针常量&q ...
- 以虎嗅网4W+文章的文本挖掘为例,展现数据分析的一整套流程
本文转自知乎 作者:苏格兰折耳喵 ----------------------------------------------------- 本文作者将结合自身经验,并以实际案例的形式进行呈现,涉及从 ...
- Facebook内部报告:争取青少年用户的鸡贼小技巧
翻译:吴祺深 欢迎访问网易云社区,了解更多网易技术产品运营经验. 去年十月,Facebook收购了TBH,最后却关闭了这款APP,不过一则内部报告透露了,通过这款流行的投票APP,这家公司学会了如何去 ...
- DevOps 工程师成长日记系列三:版本
原文地址:https://medium.com/@devfire/how-to-become-a-devops-engineer-in-six-months-or-less-part-3-versio ...
- OAuth 2.0、OIDC 原理
OAuth 目录 OAuth 什么是 OAuth? 为什么是 OAuth? SAML OAuth 和 API OAuth 主要组件 OAuth 作用域 OAuth 参与者 OAuth 令牌 OAuth ...
- [Erlang 0116] 当我们谈论Erlang Maps时,我们谈论什么 Part 1
Erlang 增加 Maps数据类型并不是很突然,因为这个提议已经进行了2~3年之久,只不过Joe Armstrong老爷子最近一篇文章Big changes to Erlang掀起不小了风 ...
随机推荐
- 安装配置Android开发环境SDK
引言: 好搞事情,搞点移动端测试高大尚的东西,首先先得把环境搭建起来: 1.下载 握了个草,很多网站都直接推荐到android官网去下载,叔不知google官网早就被我大天朝给墙了,对于不喜欢FQ的天 ...
- WPF 出现“调用线程无法访问此对象,因为另一个线程拥有该对象”
引起这种错误多半是由于在非UI线程刷新界面,解决此问题可以使用Dispatcher this.Dispatcher.Invoke(new Action(() => { UpdateUI(stri ...
- 使用python读取大文件
python中读取数据的时候有几种方法,无非是read,readline,readlings和xreadlines几种方法,在几种方法中,read和xreadlines可以作为迭代器使用,从而在读取大 ...
- SpringMVC @RequestBody请求参数在postman中的请求
使用SpringMVC框架,controller使用参数 @RequestBody LoginReq req 注解方式模拟http请求 需要请求header添加一个参数 设置 Header参 ...
- Kubernetes v1.10.x HA 全手动安装教程(TL;DR)
转自 https://www.kubernetes.org.cn/3814.html 本篇延续过往手动安装方式来部署 Kubernetes v1.10.x 版本的 High Availability ...
- 九度oj-1533 最长上升子序列 (LIS)
http://ac.jobdu.com/problem.php?pid=1533 题目描述: 给定一个整型数组, 求这个数组的最长严格递增子序列的长度. 譬如序列1 2 2 4 3 的最长严格递增子序 ...
- 查看http的并发请求数及其TCP连接状态
统计80端口的连接数据 netstat -nat | grep -i "80" | wc -l 统计httpd协议连接数 ps -ef | grep httpd | wc -l 统 ...
- Memcached在Linux环境下的使用详解http://blog.51cto.com/soysauce93/1737161
大纲 一.什么是memcached 二.memcached特性 三.memcached存储方式 四.memcached安装与配置 五.memcached结合php 六.Nginx整合memcached ...
- mysql新建用户并授权
参考:https://www.cnblogs.com/zhangdiIT/p/8116776.html
- git pull --rebase的使用
原文:http://www.cnblogs.com/kevingrace/p/5896706.html 使用下面的关系区别这两个操作:git pull = git fetch + git mergeg ...