As an “outdated” hotfix framework, Amigo is a good place to learn and understand the fundamentals of hotfix. This article is the third in this series. The first two articles:

First contact with Android hot update solution Amigo

Get up close and personal with Android hot update solution Amigo

The original author has not updated for a long time. I have adapted Android8.0 and Gradle3.0 before, and recently adapted Android P. I’m using the latest environment, Android Studio 3.4.1. Gradle plugin version 5.1.1 Gradle version 3.4.1, Kotlin version 1.3.31.

At present, it is tested on the real machine of Huawei and OnePlus and runs smoothly.

1. Gradle plugin adaptation

Gradle syntax updates

Gradle plugin code amigoplugin.groovy

File manifestFile = output.processManifest.manifestOutputDirectory
Copy the code

Left left left left down down down

File manifestFile = output.processManifest.manifestOutputDirectory.get().asFile
Copy the code

and

String manifestPath = "${output.processManifest.manifestOutputDirectory.path}/AndroidManifest.xml"
Copy the code

Left left left left down down down

String manifestPath = output.processManifest.manifestOutputDirectory.get().asFile.path+"/AndroidManifest.xml"
Copy the code

The main code here is to modify the androidmanifest.xml, change the original Application to me.ele. Amigo.Amigo, and then change the original Application to an Activity.

2. Amigo adapter AmigoInstrumentation code. Java

AmigoInstrumentation.java

When we replace the original Instrumentation of the system with our own Instrumentation, the system below Android P can run. However, Android P will throw Uninitialized ActivityThread, likely app-created Instrumentation exceptions, Obviously this is because our own Instrumentation mThread is empty.

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

        return oldInstrumentation.newActivity(cl, className, intent);
    }
Copy the code

3. AssetPath adaptation

The ensureStringBlocks method is no longer available in AssetManager on Android P. This method only needs to be called on 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);
    }
Copy the code

Left left left left down down down

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);
    }
Copy the code

The last lot.