[原创]Android Studio的Instant Run(即时安装)原理分析和源码浅析

Android Studio升级到2.0之后,新增了Instant Run功能,该功能可以热替换apk中的部分代码,大幅提高测试安装的效率。

但是,由于我的项目中自定义了一些ClassLoader,当使用InstantRun时,经常出现class加载不正确的问题。分析后原因如下。

使用Instant Run编译出的apk里面会多出几个dex文件,和一个instant-run.zip,这个zip里也是一堆dex文件:

所以推测,instant Run的实现原理是:

根据代码结构,将App的源码分割成多个dex,然后使用自定义的classloader来加载他们,当然这个自定义的classloader也要继承BaseDexClassLoader,因为BaseDexClassLoader里有个DexPathList,这个所谓的List里存的是多个dex的文件信息,所以当某段代码修改时,只需编译和替换相应的dex文件即可(这同样也是MultiDex的实现原理)。

下面我们简单验证一下。

首先正常的apk运行时,其classloader打印出来是这样的:

dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.zkw.hostdemo-1/base.apk"],nativeLibraryDirectories=[/data/app/com.zkw.hostdemo-1/lib/arm, /system/lib, /vendor/lib, system/vendor/lib, system/vendor/lib/egl, system/lib/hw]]]

而使用Instant Run运行起来的apk,其classloader打印出来长这样:

com.android.tools.fd.runtime.IncrementalClassLoader$DelegateClassLoader[DexPathList[[dex file "/data/data/com.zkw.hostdemo/files/instant-run/dex/slice-support-annotations-23.3.0_6be31c7c3de045eced09b0e58c45c46ba1a8b4da-classes.dex", dex file "/data/data/com.zkw.hostdemo/files/instant-run/dex/slice-slice_9-classes.dex", dex file "/data/data/com.zkw.hostdemo/files/instant-run/dex/slice-slice_8-classes.dex", dex file "/data/data/com.zkw.hostdemo/files/instant-run/dex/slice-slice_7-classes.dex", dex file "/data/data/com.zkw.hostdemo/files/instant-run/dex/slice-slice_6-classes.dex", dex file "/data/data/com.zkw.hostdemo/files/instant-run/dex/slice-slice_5-classes.dex", dex file "/data/data/com.zkw.hostdemo/files/instant-run/dex/slice-slice_4-classes.dex", dex file "/data/data/com.zkw.hostdemo/files/instant-run/dex/slice-slice_3-classes.dex", dex file "/data/data/com.zkw.hostdemo/files/instant-run/dex/slice-slice_2-classes.dex", dex file "/data/data/com.zkw.hostdemo/files/instant-run/dex/slice-slice_1-classes.dex", dex file "/data/data/com.zkw.hostdemo/files/instant-run/dex/slice-slice_0-classes.dex", dex file "/data/data/com.zkw.hostdemo/files/instant-run/dex/slice-ormlite-core-4.47_2aa30d6da8ed45bfc6255e592f80eb5f44eace4c-classes.dex", dex file "/data/data/com.zkw.hostdemo/files/instant-run/dex/slice-ormlite-android-4.47_a7ee90c985672a4cd4bdfca79190a330465fcdb0-classes.dex", dex file "/data/data/com.zkw.hostdemo/files/instant-run/dex/slice-lecore_4c1e07fda866033d90832ceae724962d4943e790-classes.dex", dex file "/data/data/com.zkw.hostdemo/files/instant-run/dex/slice-internal_impl-23.1.1_12c3206fb094d3315355dc809fcd39ad94f6e5e8-classes.dex", dex file "/data/data/com.zkw.hostdemo/files/instant-run/dex/slice-fastjson-1.1.45.android_317ce285230b187682809682934f3690b4d9580d-classes.dex", dex file "/data/data/com.zkw.hostdemo/files/instant-run/dex/slice-com.android.support-support-v4-23.1.1_1cfecee433501e7056d02c08b2393c569c575b33-classes.dex", dex file "/data/data/com.zkw.hostdemo/files/instant-run/dex/slice-com.android.support-multidex-1.0.1_a3117677a6ad7ee678ee3f3a4af434c4d08ee7ba-classes.dex"],nativeLibraryDirectories=[/data/app/com.zkw.hostdemo-1/lib/arm, /system/lib, /vendor/lib, system/vendor/lib, system/vendor/lib/egl, system/lib/hw]]]

很长吧,发个截图:

可以看到这个ClassLoader是:com.android.tools.fd.runtime.IncrementalClassLoader$DelegateClassLoader,DexPathList对应着instant-run.zip里的所有dex。

到这里,感觉基本符合我的猜想,但是这个IncrementalClassLoader是如何添加到设备中的,又如何在运行时起作用的,我们接着分析。

instant run运行的apk里,和class有关的就是classes.dex、classes2.dex和instant-run.zip里的dex。

通过观察命名和反编译,我发现instant-run.zip里的dex都是和我们app代码相关的,而classes.dex和classes2.dex是AndroidStudio编译时自己添加的,其中classes2.dex最重要,我们反编译看看:

终于看到了熟悉的IncrementalClassLoader,那这个classloader是怎么生效的呢,我们看看BootstrapApplication的源码(可想而知,AndroidManifest文件中的application属性也被Android Studio改了):

注意标绿的那行,继续进去看看(那行下面有个createRealApplication(),其实就是通过反射获取app自定义的Application,然后做对应的操作):

灰色的那行就是安装IncrementalClassLoader的地方,进入IncrementalClassLoader的inject()看看,

源码中可以看到,Studio其实就是利用反射,将自己的IncrementalClassLoader设置成app中默认ClassLoader的parent,这样就拦截了所有类加载的动作,从而实现了对多个dex文件的动态加载。

到此,原理分析结束。

所以如果你的app里用到了自定义的ClassLoader,请谨慎使用Instant Run!

谢谢阅读,转载请注明出处。

时间: 2024-12-17 20:10:20

[原创]Android Studio的Instant Run(即时安装)原理分析和源码浅析的相关文章

Android studio Unable to run mksdcard SDK tool

/******************************************************************************************** * Android studio Unable to run mksdcard SDK tool * 说明: * 记录Ubuntu下AS安装过程中遇到的问题. * * 2016-6-13 深圳 南山平山村 曽剑锋 *************************************************

Android Studio 1.0 苹果电脑安装配置

前言 近日Google终于不负众望,发布了期待已久的Android Studio 1.0正式版.小编自己是Android开发者,之前使用过Eclipse,也试用过Android Studio 0.x版本,感觉不错.这款正式版可以带给Android开发者非常多的惊喜. 安装和配置 前提:因为Android需要使用Java语言作为标准开发语言,所以你的操作系统里需要安装Java开发环境.如果你还没有安装Java开发环境,可以上网搜索如何下载,安装和配置环境变量,在本文中不做过多说明了,网上有很多图文

Google首推Android Studio稳定版,图解安装过程让你简单上手

Android Studio是谷歌为广大安卓开发者开发的IDE,支持Windows.Mac.Linux等操作系统,基于Java语言集成开发环境IntelliJ搭建而 成.该IDE在2013年5月的Google I/O开发者大会上首次露面,此间推出了若干个测试版,在12月8日发布的版本是Android Studio的首个稳 定版.Google称,相对于其他开发工具,Android Studio更快.更具生产力,Android Studio 1.0推出后,Google将逐步放弃对原来主要 的Andr

Android studio 的知识-----下载和安装

背景 相信大家对Android Studio已经不陌生了,Android Studio是Google于2013 I/O大会针对Android开发推出的新的开发工具,目前很多开源项目都已经在采用,Google的更新速度也很快,明显能感觉到这是Android开发的未来,那么我们还有什么理由不去拥抱未来呢? 虽然推出了很久,但是国内貌似普及的程度并不高,鉴于很多朋友求studio的详细教程,那么今天我就手把手教大家下载.安装.使用,Studio之路从这里开始. Android Studio VS Ec

Android Studio体验(一)--Window版本安装

如果说之前看见有人用Android Studio你还是不屑一顾的话,那么现在该改变态度了,正如我一样,之前一直习惯于Android内置ADT插件的捆绑Ecliple,现在Android Studio发布会已经过去了12天,年底加班加的都已经无力吐槽,更何况学习了.其实在之前自己也下载过0.8.14的版本,不过当时存在一些问题加上时间不够无奈就放弃了,换个IDE总是需要时间熟悉的.现在Android Studio已经进入了稳定版,作为亲儿子以后将成为Android开发主流的IDE,同时 Andro

Android Studio帮助文档的安装及智能提示设置

初次使用Android Studio,发现其智能提示不能像Visual Studio一样显示系统方法等的详细用途描述.经查找资料,问题原因是未安装SDK Document. 解决办法如下: 1.打开如下菜单(图一): (图一) 2.在下图二中选中Documentation for android SDK,确定后即可自动下载文档 3.下载后,可能此时仍无法弹出方法详述,这时要打开 jdk.table.xml,文件路径 /$USER_HOME$\.AndroidStudio2.3\config\op

android studio 配置 Genymotion 以及Genymotion安装配置等

1.下载安装 1-中文官网 网址:http://www.genymotion.net/ 进去后点击注册.登陆你的账号或者注册一个新的账号 2-下载 点击右上角的试用,下载下来就可以了 3-访问速度过慢的解决方法 访问http://ping.chinaz.com/  输入访问慢的网址 点击Ping检测 往下翻页 找到响应时间低的 复制其响应IP 打开文件夹 C:\Windows\System32\drivers\etc 找到hosts 将其剪贴到桌面并用记事本打开 在最后追加 响应IP Ping检

解决Android Studio 3.x版本的安装时没有SDK,运行时出现SDK tools错误

好久没更新了,最近手机上的闹钟APP没一个好用的,所以想自己写个. 那Android开发环境搭起来,注意先装好jdk. 1.安装Android Studio google的Android开发网站已经有中文版本,不用跨越GFW就能访问:https://developer.android.google.cn/ 乍一看,感觉Android Studio的安装包小了不少,既然官方提供,下载来安装再说. 安装过程中组件选择时就两个,让我明白为啥安装包小了,但也多了另一个疑问:SDK去哪了?(因为之前2.x

android studio 3.1.4下载安装配置(附旧版本下载地址)

windows下安装android studio.当前时间2018年9月. 最新版本的android studio3.2.0-release出来了,拥有许多新的特性 可能我是一个业余的android开发者原因,我看到两个点, 1.The new version of AAPT2 fixes many issues, including improved handling of non-ASCII characters on Windows. 修复了打包签名apk时用到了AAPT2的许多问题,主要