AS 2.0之Instant Run的实现原理详解 (转载)

电脑信息 2023-02-27 其他问题 15 ℃
正文

AS 2.0之Instant Run的实现原理详解 (转载)

  昨天谷歌发布了android studio 2.0预览版,各大媒体竞相刷屏,而其中新特性Instant Run让代码变动一秒生效,确实让人眼前一亮。而Instant Run的原理又是怎样的呢?你有深究过么??今天看到一位大神对Instant Run原理剖析,感觉灰常不错,分享给大家学习学习。

  Instant Run

  Instant Run实际上就是一个热补丁,但修改方法竟然不用重启Activity,这是怎么做到的?阅读一翻关于几个热补丁思路的介绍 ,你会发现andfix和dexposed采用jni hook方法,不用重启就能修复,而Nuwa的ClassLoader思路因为类被虚拟机加载后,不会重新加载,所以需要重启。Instant Run是怎么实现不重启加载的呢,难道也是jni hook?下面我们来看看其具体原理吧。

  实现原理

  和nuwa类似,一个插件一个库,Instant Run用的是gradle plugin 2.0.0-alpha1和instant-run.jar。

  gradle plugin 2.0.0-alpha1

  gradle plugin 2.0.0-alpha1主要有两个作用:

  1、第一次运行,应用 transform API 修改字节码。输出目录为 Application/build/intermediates/transforms/instantRun/debug/folders/1 。

  1)给所有的类添加 $change 字段

  $change为 IncrementalChange 类型, IncrementalChange 是个接口,该接口后面会讲。

  2)修改类的全部方法

  新的逻辑是:如果 $change 不为空,去调用 $change 的 access$dispatch 方法,参数为方法签名字符串和方法参数数组,否则调用原逻辑。

  2、后续运行,dx补丁类,生成补丁dex。输出目录为 Application/build/intermediates/transforms/instantRun/debug/folders/4000 。

  1)被修改类对应的补丁类

  补丁类,并不是你修改后的类,而是由gradle plugin自动生成,实现了 IncrementalChange 接口的类。该类类名在原名后面添加 $override ,复制修改后类的大部分方法,实现 IncrementalChange 接口的 access$dispatch 方法,该方法会根据传递过来的方法签名,调用本类的同名方法。只要把原类的 $change 字段设置为该类,那就会调用该类的 access$dispatch 方法,就会使用修改后的方法了。

  2)被修改类的记录类

  AppPatchesLoaderImpl记录了所有被修改的类,也会被打进补丁dex。

  instant-run.jar

  instant-run.jar的路径为 Application/build/intermediates/incremental-runtime-classes/debug/instant-run.jar 。

  instant-run.jar是gradle plugin帮我们自动打到dex中去的,省去了compile dependency这一步。它的主要作用有两个:

  1、设置原类的 $change 字段为补丁类

  需要对被修改的类设置 $change 字段,那怎么知道哪些类被修改了?

  AppPatchesLoaderImpl类不但记录了全部被修改的类,还提供 load 方法支持设置被修改原类 $change 字段,当收到补丁通知时,只需新建一个DexClassLoader,去反射加载补丁dex中的 AppPatchesLoaderImpl 类,调用load方法即可,load方法中会去加载全部补丁类,并赋值给对应原类的 $change 。

  2、重启加载补丁类

  重启后怎么办?原来的补丁文件需要加载进来。

  IncrementalClassLoader会在Application中去加载该应用cache目录中的补丁dex,把它设置为默认 PathClassLoader 的parent,由于ClassLoader采用双亲委托模型,会先去parent查找类,所以就可以加载补丁类了。

  结束语

  虽然 android studio 2.0的Instant Run新特性很赞,不用重新启动,但也还是有一些局限之处,比如变量、添加删除方法等等,相信谷歌后续会持续进行优化。相比不足,从官方介绍中我们也可以了解到,android studio 2.0的各种特性,确实还是足以让广大开发者选择它了。

  相关文章:《Android React Native中如何封装使用原生UI组件》 /

本文TAG:

红山根电脑信息网