Instant Run工作原理

普通应用加载流程

Instant Run工作原理_第1张图片
Paste_Image.png

Instant Run应用加载流程

Instant Run工作原理_第2张图片
Paste_Image.png

会在编译过程中修改AndroidManifest。加入Application和Appserver的代码。

最后的apk中会有classes.dex和classes2.dex两个dex文件,原来的代码会如instant-run.zip文件

Instant Run工作原理_第3张图片
Paste_Image.png

classes.dex反编译后

Instant Run工作原理_第4张图片
Paste_Image.png

classes2.dex反编译后

Instant Run工作原理_第5张图片
Paste_Image.png

instant-run.zip中的内容,为我们自己的代码

Instant Run工作原理_第6张图片
Paste_Image.png

AndroidManifest中application被替换为BootstrapApplication

Instant Run工作原理_第7张图片
Paste_Image.png

BootstrapApplication的attachBaseContext

createResources → setupClassLoaders → createRealApplication → 调用realApplication的attachBaseContext

createResources:

检查resource有没有改变

setupClassLoaders

设置IncrementalClassLoader到loader链条中

Instant Run工作原理_第8张图片
Paste_Image.png

Application的OnCreate

monkeyPatchApplication → monkeyPatchExistingResources → Server启动 → 调用realApplication的onCreate方法

monkeyPatchApplication

1.替换ActivityThread的mInitialApplication为realApplication
2.替换mAllApplications 中所有的Application为realApplication
3.替换ActivityThread的mPackages,mResourcePackages中的mLoaderApk中的application为realApplication。

monkeyPatchExistingResources

如果resource.ap_文件有改变,那么新建一个AssetManager对象newAssetManager,然后用newAssetManager对象替换所有当前Resource、Resource.Theme的mAssets成员变量。 2.如果当前的已经有Activity启动了,还需要替换所有Activity中mAssets成员变量

热部署
Server启动后会监听socket,当命令为1,且patch路径为classes.dex.3,则是HotSwapPatch

先将patch的dex文件写入到临时目录,然后使用DexClassLoader(父classloader为PathClassloader)去加载dex。然后反射调用AppPatchesLoaderImpl类的load方法,需要说明的是,AppPatchesLoaderImpl继承自抽象类AbstractPatchesLoaderImpl,并实现了抽象方法:getPatchedClasses

在第一次构建apk时,在每一个类中注入了一个$change的成员变量,它实现了IncrementalChange接口,并在每一个方法中,插入了一段类似的逻辑。

    IncrementalChange localIncrementalChange = $change;
        if (localIncrementalChange != null) {
            localIncrementalChange.access$dispatch(
                    "onCreate.(Landroid/os/Bundle;)V", new Object[] { this,
                            ... });
            return;
    }

增量编译时,会把修改类的名称会从AppPathcesLoaderImpl的getPatchedClasses方法中返回,并生成修改类的名称+$overide的类并实现IncrementalChange 接口,把修改的方法放在里面。load方法会加载$overide类,放入原来修改类的$change变量中。

冷部署
patch路径以dex结尾时

把dex文件写到私有目录,等待整个app重启,重启之后,使用前面提到的IncrementalClassLoader加载dex即可。

IncrementalClassLoader的作用为从私有目录中加载class文件

你可能感兴趣的:(Instant Run工作原理)