Brief Introduction to the Access of Aliyun Sophix Thermal Repair Framework

Posted by NiallThistle on Tue, 03 Sep 2019 12:21:15 +0200

Brief Introduction to the Access of Aliyun Sophix Thermal Repair Framework

At present, Android development hot repair can be said to be a basic function of a standard commercial project, which is convenient for emergency problem repair after online. (ps, no matter how you test it, app s that seem to be online always have some bugs that you can't find during the test, (viii) instead of comparing AndFix, Robust and tinker/bugly. The current heat is undoubtedly Ali's sophix and Tencent's tinker.

First try tinker/bugly access, but because Tinker does not support gradle 5 or above version compatibility, and our project uses androidx and jetpack and other technical points, compiler platform is also the latest configuration, so it can not be downgraded to adapt tinker, and tinker access is really complex, so try sophix and test OK. Here's the record. It's better to give some help to the students who need it.

I. Access Preparedness File

  • Registered with Aliyun Account Aliyun
  • Personal Account Console Add Products
  • Download the configured aliyun-emas-service.json file
  • Download the auxiliary debugging tool hotfix-debug-tool.apk and the corresponding platform patch generation tool tool

II. Project Configuration

  • Configure add under build.gradle in the project root directory

    repositories {
       //Add Aliyun Warehouse
       maven {url "http://maven.aliyun.com/nexus/content/repositories/releases"}
    }
    
  • Add dependencies to build.gradle at the directory level of the app project

    implementation "com.aliyun.ams:alicloud-android-hotfix:3.2.8"//The latest edition
    
  • Add and configure the appropriate permissions according to the official documents (generally speaking, the project should have the following permissions)

    <! -- network right -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <! -- External Storage Read Rights, Debugging Tools Load Local Patches Need -->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    
  • Adding confusion rules

    #Use the baseline package to generate mapping.txt
    -printmapping mapping.txt
    #The generated mapping.txt is moved to / APP under the app/build/outputs/mapping/release path
    #Use of repaired projects to ensure consistent confusion results
    #-applymapping mapping.txt
    #hotfix
    -keep class com.taobao.sophix.**{*;}
    -keep class com.ta.utdid2.device.**{*;}
    -dontwarn com.alibaba.sdk.android.utils.**
    #Prevent inline
    -dontoptimize
    

    Let's note that the results of individual project testing are that neither the baseline package nor the fix package need to be modified, such as the confusion rules above. Also, don't remove # - applymapping maping.txt and don't manually copy the file to the corresponding directory. Otherwise, compilation errors of R8 errors may occur.

3. Code Settings

Note here that fast access is not recommended, but robust access, and hot repair is not recommended by emas-service.json.

  • Create the implementation class of Application, which is the real industrial implementation class of the specific application of App, such as MyReal Application.

  • Creating an implementation class of sophix Application, without storing any other logic, is only the initialization of sophix, and it is important not to refer to classes other than Android SDK standard library classes, otherwise it is easy to make mistakes when building patches.

    package com.my.pkg;
    import android.app.Application;
    import android.content.Context;
    import android.support.annotation.Keep;
    import android.util.Log;
    import com.taobao.sophix.PatchStatus;
    import com.taobao.sophix.SophixApplication;
    import com.taobao.sophix.SophixEntry;
    import com.taobao.sophix.SophixManager;
    import com.taobao.sophix.listener.PatchLoadStatusListener;
    import com.my.pkg.MyRealApplication;
    /**
     * Sophix The entry class, which is designed to initialize Sophix, should not contain any business logic.
     * This class must inherit from SophixApplication, and the onCreate method does not need to be implemented.
     * This class should not have any logic to call each other with other classes in the project, and must be completely isolated.
     * AndroidManifest Set application to this class in SophixEntry and the original Application class in SophixEntry.
     * Note that there is no need to reinitialize Sophix in the original Application, and you need to avoid confusing the original Application class.
     * If there are other custom modifications, please consult the authorities and handle them properly.
     */
    public class SophixStubApplication extends SophixApplication {
        private final String TAG = "SophixStubApplication";
        // Here SophixEntry should specify the real Application and ensure that the RealApplication Stub class name is not confused.
        @Keep
        @SophixEntry(MyRealApplication.class)
        static class RealApplicationStub {}
        @Override
        protected void attachBaseContext(Context base) {
            super.attachBaseContext(base);
    //         If you need to use MultiDex, you need to call it here.
    //         MultiDex.install(this);
            initSophix();
        }
        private void initSophix() {
            String appVersion = "0.0.0";
            try {
                appVersion = this.getPackageManager()
                                 .getPackageInfo(this.getPackageName(), 0)
                                 .versionName;
            } catch (Exception e) {
            }
            final SophixManager instance = SophixManager.getInstance();
            instance.setContext(this)
                    .setAppVersion(appVersion)
                    .setSecretMetaData("idSetret", "appSecret", "rsaSecret")//Here, configure the necessary key, which is available in emas-service.json.
                    .setEnableDebug(true)
                    .setEnableFullLog()
                    .setPatchLoadStatusStub(new PatchLoadStatusListener() {
                        @Override
                        public void onLoad(final int mode, final int code, final String info, final int handlePatchVersion) {
                            if (code == PatchStatus.CODE_LOAD_SUCCESS) {
                                Log.i(TAG, "sophix load patch success!");
                            } else if (code == PatchStatus.CODE_LOAD_RELAUNCH) {
                                // If you need to restart in the background, it is recommended that SharePreference be used to save the status here.
                                Log.i(TAG, "sophix preload patch success. restart app to make effect.");
                            }
                        }
                    }).initialize();
        }
    }
    

    One more thing to note here is how to write the Kotlin version. The key is the kotlin transformation of the static internal class in java. Don't write the object, but the following (I haven't tried whether componain object Real Application Stub is feasible).

    ....
    //Here @keep is inside the support package, which is used to preserve and prevent confusion. If there are no support packages, you need to configure obfuscation rules
    	@Keep
    	@SophixEntry(MyRealApplication::class)
    	internal class RealApplicationStub
    ...
    
    ####Configuration of confusion rules
    -keepclassmembers class com.my.pkg.MyRealApplication {
        public <init>();
    }
    # If you don't use android.support.annotation.Keep, you need to add this line
    # -keep class com.my.pkg.SophixStubApplication$RealApplicationStub
    
  • Then under the Application node in Android Manifest. xml, name="SophixStubApplication" replaces the MyReal Application of the original business.

** Note: ** The onCreate configuration in the Business Application is the necessary initialization in the MyReal Application of the sample. Since the attachBaseContext function is called before onCreate, if there is a function initialized in attachBaseContext in the business application, it is not necessary to move to onCreate. It is necessary to put it in Sophix Stub Application, and pay attention to the order of initSophix.

  • Invoke requests where necessary, such as in MyReal Application's onCreate, or where patches need to be requested

    // QueyAndLoadNewPatch cannot be placed in attachBaseContext, otherwise it has no network privileges. It is recommended that it be placed at any later time, such as onCreate.
    SophixManager.getInstance().queryAndLoadNewPatch();
    
  • tag can also be set for gray test debugging, distinguishing between the environment

    List<String> tags = new ArrayList<>();
    tags.add("test");
    //This call precedes the queryAndLoadNewPatch() method
    SophixManager.getInstance().setTags(tags)

IV. Patch Generation

  1. Generate baseline packages

    Normal configuration, build release version of the apk. Stored as old.apk

  2. After repairing the required Bug, the repaired release package, tentatively named new.apk, is generated.

  3. Then use the patch generation tool for the corresponding version of windows or Mac or Linux platform (which is required to download at the beginning of the article), configure and select old.apk and new.apk, and set the patch output path, etc. Note that configuring release's signature keystore for patch signatures, and that if the project uses androidx, patch tools may not be compatible, and errors will be reported. Cancel the initialization check in the settings and patch it again.

  4. The generated patches are uploaded to the background of Aliyun thermal repair, the corresponding version of the patches are configured, and then the patches are created - uploaded patches - first local two-dimensional code test - gray test - release patches.

** Note: ** Debugging debug-tool.apk may not work properly on all mobile phones, and some models cannot connect to debugged applications. You can try another one. Also, Aliyun's sophix has a free quota, and the excess is charged. When uploading patches, your account will fail to upload if it is in arrears. But the prompt text is still a request failure, try again later and so on.

Topics: Android Gradle JSON Maven