Instant Run在第一次构建APK时,使用ASM在每一个方法中注入了类似的代码逻辑:当Change不为Null时,则调用他的access dispatch方法,参数为具体的方法名和方法参数。当MainActivity的onCreate方法做了修改,就会生成替换类MainActivity
change设置为MainActivity Override
最后change就不会为null,则会执行MainActivity Override
dispatch方法,最终会执行onCreate方法,从而实现了onCreate方法的修改。
借鉴Instant Run原理的热修复框架有Robust和Aceso。
动态链接库修复:
重新加载so。
加载so主要用到了System类的load和loadLibrary方法,最终都会调用到nativeLoad方法。其会调用JavaVMExt的LoadNativeLibrary函数来加载so。
so修复主要有两个方案:
- 1、将so补丁插入到NativeLibraryElement数组的前部,让so补丁的路径先被返回和加载。
- 2、调用System的load方法来接管so的加载入口。
为什么选用插件化?
在Android传统开发中,一旦应用的代码被打包成APK并被上传到各个应用市场,我们就不能修改应用的源码了,只能通过服务器来控制应用中预留的分支代码。但是很多时候我们无法预知需求和突然发生的情况,也就不能提前在应用代码中预留分支代码,这时就需要采用动态加载技术,即在程序运行时,动态加载一些程序中原本不存在的可执行文件并运行这些文件里的代码逻辑。其中可执行文件包括动态链接库so和dex相关文件(dex以及包含dex的jar/apk文件)。随着应用开发技术和业务的逐步发展,动态加载技术派生出两个技术:热修复和插件化。其中热修复技术主要用来修复Bug,而插件化技术则主要用于解决应用越来越庞大以及功能模块的解耦。详细点说,就是为了解决以下几种情况:
- 1、业务复杂、模块耦合:随着业务越来越复杂,应用程序的工程和功能模块数量会越来越多,一个应用可能由几十甚至几百人来协同开发,其中的一个工程可能就由一个小组来进行开发维护,如果功能模块间的耦合度较高,修改一个模块会影响其它功能模块,势必会极大地增加沟通成本。
- 2、应用间的接入:当一个应用需要接入其它应用时,如淘宝,为了将流量引流到其它的淘宝应用如:飞猪旅游、口碑外卖、聚划算等等应用,如使用常规技术有两个问题:可能要维护多个版本的问题或单个应用体积将会非常庞大的问题。
- 3、65536限制,内存占用大。
插件化的思想:
安装的应用可以理解为插件,这些插件可以自由地进行插拔。
插件化的定义:
插件一般是指经过处理的APK,so和dex等文件,插件可以被宿主进行加载,有的插件也可以作为APK独立运行。
将一个应用按照插件的方式进行改造的过程就叫作插件化。
插件化的优势:
- 低耦合
- 应用间的接入和维护更便捷,每个应用团队只需要负责自己的那一部分。
- 应用及主dex的体积也会相应变小,间接地避免了65536限制。
- 第一次加载到内存的只有淘宝客户端,当使用到其它插件时才会加载相应插件到内存,以减少内存占用。
插件化框架对比:
- 最早的插件化框架:2012年大众点评的屠毅敏就推出了AndroidDynamicLoader框架。
- 目前主流的插件化方案有滴滴任玉刚的VirtualApk、360的DroidPlugin、RePlugin、Wequick的Small框架。
- 如果加载的插件不需要和宿主有任何耦合,也无须和宿主进行通信,比如加载第三方App,那么推荐使用RePlugin,其他情况推荐使用VirtualApk。由于VirtualApk在加载耦合插件方面是插件化框架的首选,具有普遍的适用性,因此有必要对它的源码进行了解。