虚位以待(AD)
虚位以待(AD)
首页 > 软件编程 > Android编程 > Android Studio Instant Run的工作原理

Android Studio Instant Run的工作原理
类别:Android编程   作者:码皇   来源:互联网   点击:

Instant Run是Android Studio2 0以上版本引入的一个新特性,它可以显著地减少应用编译及部署的时间。Instant Run是一个神奇的功能,为什么这么说呢?当第一次你点击run或debug按钮的时候,跟正常的编译部署

Instant Run是Android Studio2.0以上版本引入的一个新特性,它可以显著地减少应用编译及部署的时间。

Instant Run是一个神奇的功能,为什么这么说呢?当第一次你点击run或debug按钮的时候,跟正常的编译部署流程是一样的;当你对代码做了一些修改,然后再次点击run或debug按钮(这时旁边会出现一个?标志),接下来就是见证奇迹的时候了,你甚至还没来得及将注意力从Android Studio转移到手机上来,应用已经编译部署好了,这就是它的神奇之处。

接下来就是了解Instant Run的工作原理了,这里有一个官方视频连接:Instant Run:An Android Tool Time Deep Dive,有兴趣的朋友可以直接点开看。

Instant Run的特点

上图为应用程序一般的编译和部署过程:

  1. 编译

  2. 部署安装

  3. App启动

  4. Activity启动

经过以上几个步骤之后才能看到代码修改的效果。

对比通用的编译部署过程,Instant Run的目标就很清晰了:

  1. 尽可能去掉上述过程中不必要的步骤

  2. 让剩下的必要步骤越快越好

上述两点在实际中表现为:

  • 仅对增量和变化做编译和部署

  • 尽量不要重新安装App

  • 尽量不要重启App

  • 甚至不要重启Activity

Instant Run = Incremental build + Hot, Warm, or Cold swap

这里写图片描述

由上图可知,Instant Run可以理解为增量编译和部署(分为Hot Swap、Warm Swap和Cold Swap三种方式)。

Hot Swap:此种方式不需要重启App,甚至不需要重启Activity就能看到代码修改引起的变化,一般适用于某个方法实现中的微小改动,如Toast或某个String字串的内容修改。

Warm Swap:此种方式需要重启Activity才能看到修改导致的变化,经常用于资源相关的代码改变。

Cold Swap:此种方式需要App重启,但并不需要App重新安装,适用于结构性的代码修改如继承关系或方法签名改变。

正常的构建流程

Manifest文件会被合并,然后与资源文件一起被AAPT工具打包;同时java文件也被编译为字节码,然后转成dex文件,最终上述文件一起打包成APK。

使用Instant Run的构建流程

字节码被添加到.class文件中,同时一个appserver类被注入到APK中。

另外还会添加一个新的Application类定义,它用来注入自定义的类加载器用来调起App Server,因此Manifest也会被修改以便可以使用它。如果你已创建了自己的Application类,Instant Run将会使用新的来代理你的Application。

现在Instant Run就跑起来了,所以当你修改了部分代码,然后再次点击run或者debug时,Instant Run将会使用Hot Swap、Warm Swap或者Cold Swap尽可能地缩短原来的构建过程。

Hot Swapping

在开发过程中,Android Studio会监控哪些文件发生了变化,并使用Gradle工具为那些变化的class文件生成dex文件。

这些新的dex文件被Android Studio挑选出来然后部署到我们应用上的App Server上。

由于原始版本的class文件已经存在于运行的App中,Gradle可以高效地将更新的文件替换掉以前的旧文件,这些新文件可以被App Server使用自定义的类加载器加载。

随后,每次当应用中的一个方法被调用时,App Server会跟原始文件通信来检查他们是否被更新了。如果是的话,更新文件中的修改过的新方法会被委托来执行。

如上图,如果你设了断点你将会看到被覆盖的方法的调用栈情况。

对于方法实现的微小改变,使用重定向方法的方式可以很好地工作,但是某些需要Activity重启才能加载的情况又如何呢?

Warm Swapping

Warm Swap会重启Activity,资源会在Activity启动时加载,因此对资源的修改会要求重启Activity来实现资源的重新加载。

目前,对资源的任何修改将会导致资源重新打包与部署到App,Android Studio的技术人员也在研究资源的增量打包与部署技术。

需要注意的是当Manifest中引用的资源被修改时,或者Manifest文件本身被修改了,Warm Swap并不能工作,因为Manifest中的配置信息是在APK被安装时读取的。对Manifest的修改或其引用到的资源的修改将会触发完整的编译和部署流程。

不幸的是,重启Activity并不能应用于结构变化。添加、删除或者修改注记、静态或实例方法签名,或者修改父类、静态初始化逻辑都将需要Cold Swap方式。

Cold Swapping

应用被部署时会被分割为多个部分,每一部分都有自己的dex文件,class文件根据它们的包名被分配到不同的部分。当使用Cold Swap部署时,一个修改过的类必须与其在同一dex中的其他类一起重新生成dex,然后才能部署到目标设备。

这种方式依赖于multidex机制,仅在Android5.0(API level 21)或更高设备上才支持。

对于低于API level 20的设备而言,使用的是Dalvik模式,因此不支持Instant Run,则会执行完整的APK安装过程。

Instant Run很聪明,但它不能回退

由于Hot Swap和Warm Swap不会重启应用,因此修改某些在应用启动时才会初始化的代码时,必须重启App才能看到对应的效果。

其他

Instant Run是由Android Studio控制的,因此要从IDE中启动run或debug,而不是从手机设备中启动或重启应用。

Instant Run目前仅在主线程上支持的最好,因此如果应用使用了多线程,在其他线程上使用Hot Swap与Warm Swap将会降级为Cold Swap,如果API level小于21的话直接转为完整构建与部署。

Instant Run也在不断改进,Android Studio团队也在开发新技术让更多的情况可以支持Hot Swap,减少Cold Swap甚至完整构建,相信Android Studio后面的版本越来越好用。

相关热词搜索: