與Android熱更新方案Amigo的再次接觸

Amigo做爲一個「過氣」的的熱修復框架,用來學習和了解一下熱修復的基本原理仍是很好的。本文是本系列的第三篇。 前兩篇:java

與Android熱更新方案Amigo的初次接觸git

與Android熱更新方案Amigo的親密接觸github

原做者已經好久沒有更新的,我以前適配了Android8.0 和gradle3.0,最近適配的Android P。 我使用的是最新的環境Android Studio 3.4.1。gradle 插件版本5.1.1 gradle版本 3.4.1 ,kotlin版本1.3.31。bash

目前在華爲和一加的真機上測試,運行順利。app

1.gradle插件方面的適配

主要是gradle語法升級框架

gradle插件代碼AmigoPlugin.groovyide

File manifestFile = output.processManifest.manifestOutputDirectory
複製代碼

↓↓↓↓post

File manifestFile = output.processManifest.manifestOutputDirectory.get().asFile
複製代碼

and學習

String manifestPath = "${output.processManifest.manifestOutputDirectory.path}/AndroidManifest.xml"
複製代碼

↓↓↓↓測試

String manifestPath = output.processManifest.manifestOutputDirectory.get().asFile.path+"/AndroidManifest.xml"
複製代碼

這裏代碼主要是修改AndroidManifest.xml,把原來的Application修改爲me.ele.amigo.Amigo,而後把原來的Application修改爲一個Activity。

2.Amigo代碼適配 AmigoInstrumentation.java

AmigoInstrumentation.java

咱們把系統原先的Instrumentation替換成咱們本身的Instrumentation的時候,在Android P如下的系統是能夠運行的,可是在Android P上就會拋出Uninitialized ActivityThread, likely app-created Instrumentation的異常,顯然這是由於咱們本身的Instrumentation的mThread爲空致使的。

@Override
    public Activity newActivity(ClassLoader cl, String className,
                                Intent intent)
            throws InstantiationException, IllegalAccessException,
            ClassNotFoundException {

        return oldInstrumentation.newActivity(cl, className, intent);
    }
複製代碼

3.AssetPath的適配

在Android P上AssetManager中已經沒有了ensureStringBlocks方法了,根據網上的資料,這個方法只是須要在Android Kiakat上調用。

static void loadPatchResources(Context context, String checksum) throws Exception {
        AssetManager newAssetManager = AssetManager.class.newInstance();
        invokeMethod(newAssetManager, "addAssetPath", PatchApks.getInstance(context).patchPath(checksum));
        invokeMethod(newAssetManager, "ensureStringBlocks");
        replaceAssetManager(context, newAssetManager);
    }
複製代碼

↓↓↓↓

static void loadPatchResources(Context context, String checksum) throws Exception {
        AssetManager newAssetManager = AssetManager.class.newInstance();
        invokeMethod(newAssetManager, "addAssetPath", PatchApks.getInstance(context).patchPath(checksum));
        if (Build.VERSION.SDK_INT <= 26) {
            invokeMethod(newAssetManager, "ensureStringBlocks");
        }
        replaceAssetManager(context, newAssetManager);
    }
複製代碼

最後github

相關文章
相關標籤/搜索