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!

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

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

  1. AndroidKiller报.smali文件丢失问题解决(关闭Android Studio的Instant Run)

    第一节编写一个Android程序里我们生成了一个验证激活码的apk,当我们输入的激活码正确时才能注册成功,输入错误时注册失败. 现在我们想输入错误的激活码也能注册.我们用Android反编译工具进行反 ...

  2. android studio2.0出现的gradle问题,instant Run即时运行不了.

    android studio 2.0出现的gradle问题: instant Run即时运行不了.经历了几乎9个preView版本的AS2.0,终于迎来了正式版,然而晴天我的霹雳,好不容易装好的2.0 ...

  3. Android新特性Instant Run详解

    关于 Instant Run Android Studio 2.0 中引入的 Instant Run 是 Run 和 Debug 命令的行为,可以大幅缩短应用更新的时间.尽管首次构建可能需要花费较长的 ...

  4. Android Studio和SDK下载、安装和环境变量配置

    win10下Android Studio和SDK下载.安装和环境变量配置                                                               - ...

  5. Android studio Unable to run mksdcard SDK tool

    /******************************************************************************************** * Andr ...

  6. Android Studio(一):介绍、安装、配置

    Android Studio相关博客: Android Studio(一):介绍.安装.配置 Android Studio(二):快捷键设置.插件安装 Android Studio(三):设置Andr ...

  7. Android Studio 1.0 苹果电脑安装配置

    ​ 前言 近日Google终于不负众望,发布了期待已久的Android Studio 1.0正式版.小编自己是Android开发者,之前使用过Eclipse,也试用过Android Studio 0. ...

  8. Android Studio中mac上面的安装

    Android Studio中mac上面的安装 学习了:https://blog.csdn.net/xianrenli38/article/details/79347170 http://www.an ...

  9. Android Studio 和 SDK 下载、安装和环境变量配置

    转Android Studio 和 SDK 下载.安装和环境变量配置https://blog.csdn.net/hahahhahahahha123456/article/details/8065135 ...

随机推荐

  1. 【原创】Windows Server 文件夹权限小问题

    服务器:Windows Server 2008 R2 Standard 做文件服务器 问题:在资源管理器里给账号设置了R/W权限,但是一直有问题,写失败. 解决:需要在server manager-r ...

  2. 大熊君说说JS与设计模式之------中介者模式Mediator

    一,总体概要 1,笔者浅谈 我们从日常的生活中打个简单的比方,我们去房屋中介租房,房屋中介人在租房者和房东出租者之间形成一条中介.租房者并不关心他租谁的房.房东出租者也不关心他租给谁.因为有中介的存在 ...

  3. Linux上成功编译CoreCLR源代码

    >>Build日期:2015-2-5下午(编译失败). 开始Linux发行版用的是CentOS 6.5,操作步骤: 1)配置git: git config --global http.ss ...

  4. 实际遭遇并解决:类型“ASP.global_asax”同时存在的问题

    将一个ASP.NET项目由预编译方式改为动态编译方式时,删除了bin文件夹中所有扩展名为.compiled文件以及文件名以App_Web_开头的文件. 访问却出现下面的错误: System.Web.H ...

  5. 应用SQLServer For XML 生成XML避免在C# 拼字符串

    最近在Review代码时,有一个功能是 查询数据库中一列,然后生成像 <rootelements>      <col>a</col>      <col&g ...

  6. JSP的那些事儿(2)---- DWR2.0 的配置和使用

    JSP的那些事儿(2)----DWR2.0 的配置和使用 分类: Web开发 JAVA 2009-04-23 15:43 999人阅读 评论(0) 收藏 举报 jspdwrjavascriptserv ...

  7. JsRender for index 循环索引使用说明

    循环是模版引擎必不可少的一部分,而说起循环,会引出一个至关重要的因素:索引. 所谓索引,即循环次数,通过索引,可以获取当前循环是第几次. 如果读者阅读过官方文档,会见到如下获取索引的方式: data: ...

  8. Java中的Set, List, Map漫谈

    在编程语言中,集合是指代表一组对象的对象.Java平台专门有一个集合框架(Collections Framework).集合框架是指表示和操作集合的统一架构,隔离了集合的操作和实现细节. 集合框架中的 ...

  9. atitit.修复xp 操作系统--重装系统--保留原来文件不丢失

    atitit.修复xp 操作系统--重装系统--保留原来文件不丢失 1. 修复目标...保持c盘文件,恢复system文件走ok... 1 2. 重装系统以前的操作 1 2.1. 避免格式化c盘/gh ...

  10. paip.powerdesign cdm pdm文件 代码生成器 java web 页面 实现

    paip.powerdesign cdm pdm文件 代码生成器 java web 页面 实现 准备从pd cdm生成java web 页面...但是,ms无直接地生成软件.... 只好自己解析cdm ...