当咱们在谈论multidex65535时,咱们在谈论什么

本文来自网易云社区android


做者:郑文git


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

原理

multidex技术原理能够分红两个部分:web

  • 在app启动时,经过Multidex.install api,扩展ClassLoader的dexElements数组来存储全部dex,这个流程会根据android sdk版本的不一样作不一样的处理,整个流程彻底经过反射完成。api

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

Multidex.install

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

咱们的解决方案

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

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

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

  • 兼容网易安所有门的加壳方案

  • 支持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

相关文章
相关标签/搜索