安卓热修复—阿里Sophix

3,260 阅读4分钟

一、概述

随着技术的高速发展与创新,热修复如雨后春笋般涌现,如美团的Robust、饿了么的Amigo、微信的Tinker以及阿里的Andfix和Sophix。站在巨人的肩膀上,可以让我们视野更加开阔,现在就跟随我一起集成阿里的Sophix吧! 滴滴滴,开车啦……

二、热修复方案对比

这里写图片描述

可以看出阿里的这款热修复产品不仅支持的替换类型全面,而且接入灰常easy,小伙伴们有木有很激动啊,之前集成过微信的Tinker,确实比Sophix稍微复杂一点!

三、准备工作

创建阿里账号,选择移动热修复,创建产品,创建应用,这样一套技能就可以mscp啦,最后是这样的:

这里写图片描述

这里写图片描述

提醒一下,集成这个产品需要实名认证的,所以我用的支付宝登录!!!

四、集成步骤

接下来是放大招开启carry模式的时刻啦……

1、在project的gradle中添加maven仓库:

 buildscript {

    repositories {
        jcenter()
        maven {
            url "http://maven.aliyun.com/nexus/content/repositories/releases"
        }
        google()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.1'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
        maven {
            url "http://maven.aliyun.com/nexus/content/repositories/releases"
        }
        google()
    }
}   

2、app的gradle添加阿里的远程依赖:

 implementation 'com.aliyun.ams:alicloud-android-hotfix:3.1.8'

3、manifest配置相关信息:

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.INTERNET"/>

       <!--热修復meta-data-->
        <meta-data
            android:name="com.taobao.android.hotfix.IDSECRET"
            android:value="IDSECRET"/>
        <meta-data
            android:name="com.taobao.android.hotfix.APPSECRET"
            android:value="APPSECRET"/>
        <meta-data
            android:name="com.taobao.android.hotfix.RSASECRET"
            android:value="RSASECRET"/>
        <!--热修復meta-data-->

3、代码中需要添加的类: 新建一个SophixStubApplication类继承SophixApplication ,并在manifest指定SophixStubApplication类:


/**
 * Created by lin on 2017/12/19.
 */

public class SophixStubApplication extends SophixApplication {
    private final String TAG = "SophixStubApplication";

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
//         如果需要使用MultiDex,需要在此处调用。
//         MultiDex.install(this);
        initSophix();
    }
    @Override
    public void onCreate() {
        super.onCreate();
        // queryAndLoadNewPatch不可放在attachBaseContext 中,否则无网络权限,建议放在后面任意时刻,如onCreate中
        /** 补丁在后台发布之后, 并不会主动下行推送到客户端, 客户端通过调用queryAndLoadNewPatch方法查询后台补丁是否可用*/
        SophixManager.getInstance().queryAndLoadNewPatch();
    }

    private void initSophix() {
        String appVersion = "1.0";
        try {
            appVersion = this.getPackageManager()
                    .getPackageInfo(this.getPackageName(), 0)
                    .versionName;
        } catch (Exception e) {
        }
        final SophixManager instance = SophixManager.getInstance();
        Log.e("lin", "appVersion= " + appVersion);
        instance.setContext(this)
                .setAppVersion(appVersion)
                .setSecretMetaData(null, null, null)
                .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.e(TAG, "sophix load patch success!");
                        } else if (code == PatchStatus.CODE_LOAD_RELAUNCH) {
                            // 如果需要在后台重启,建议此处用SharePreference保存状态。
                            Log.e(TAG, "sophix preload patch success. restart app to make effect.");
                        }else{
                            Log.e("lin", "code= " + code);
                            Log.e("lin", "mode= " + mode);
                            Log.e("lin", "info= " + info);
                            Log.e("lin", "handlePatchVersion= " + handlePatchVersion);
                        }
                    }
                }).initialize();
    }


    // 此处SophixEntry应指定真正的Application,并且保证RealApplicationStub类名不被混淆。
    @Keep
    @SophixEntry(MyRealApplication.class)
    static class RealApplicationStub {
    }

}

新建一个MyRealApplication类继承Application:

/**
 * Created by lin on 2017/12/19.
 */

public class MyRealApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        Log.e("lin", "MyRealApplication start" );
    }
}

稍微看一下PatchStatus 类:

public class PatchStatus {
    public static final int CODE_LOAD_SUCCESS = 1;
    public static final int CODE_ERR_INBLACKLIST = 4;
    public static final int CODE_REQ_NOUPDATE = 6;
    public static final int CODE_REQ_NOTNEWEST = 7;
    public static final int CODE_DOWNLOAD_SUCCESS = 9;//差异包加载成功
    public static final int CODE_DOWNLOAD_BROKEN = 10;
    public static final int CODE_UNZIP_FAIL = 11;
    public static final int CODE_LOAD_RELAUNCH = 12;//差异包加载成功,重启生效
    public static final int CODE_REQ_APPIDERR = 15;
    public static final int CODE_REQ_SIGNERR = 16;
    public static final int CODE_REQ_UNAVAIABLE = 17;
    public static final int CODE_REQ_SYSTEMERR = 22;
    public static final int CODE_REQ_CLEARPATCH = 18;//停止推送
    public static final int CODE_PATCH_INVAILD = 20;
    ......
}

4、添加混淆:

#sophix
#基线包使用,生成mapping.txt
  -printmapping mapping.txt
  #生成的mapping.txt在app/buidl/outputs/mapping/release路径下,移动到/app路径下
  #修复后的项目使用,保证混淆结果一致
  #-applymapping mapping.txt
  #hotfix
  -keep class com.taobao.sophix.**{*;}
  -keep class com.ta.utdid2.device.**{*;}

 -keepclassmembers class com.lin.opensourcelist.SophixStubApplication{
  public <init>();
}
# 如果不使用android.support.annotation.Keep则需加上此行
# -keep class com.my.pkg.SophixStubApplication$RealApplicationStub

好了,通过以下步骤,基本的功能已经初始化ok啦,现在来验证一下是否可行……

五、验证

1、添加版本号(与gradle中的需要一致):
这里写图片描述

2、生成补丁包:

下载打包工具

patch补丁包生成需要使用到打补丁工具SophixPatchTool, 如还未下载打包工具,请前往下载Android打包工具。

Mac版本打包工具地址:ams-hotfix-repo.oss-cn-shanghai.aliyuncs.com/SophixPatch…

Windows版本打包工具地址:ams-hotfix-repo.oss-cn-shanghai.aliyuncs.com/SophixPatch…

Linux版本打包工具地址:ams-hotfix-repo.oss-cn-shanghai.aliyuncs.com/SophixPatch…

调试工具地址:ams-hotfix-repo.oss-cn-shanghai.aliyuncs.com/hotfix_debu…

这里写图片描述
直接把有问题的安装包与修复后的安装包选择上,其他都不用设置,然后点击GO!就生成了差异jar包:

这里写图片描述

3、发布补丁包:

点击上传补丁:

这里写图片描述

点击查看详情:

这里写图片描述

现在就可以通过测试工具验证是否补丁包发送成功 首先连接你的应用:

这里写图片描述

然后扫描二维码:

这里写图片描述

出现以上信息说明差异包加载成功,这样给的提示是需要重启应用才生效: 修复之前的界面:

这里写图片描述

重启之后的界面:

这里写图片描述

验证成功就可以发布了,这里可以采用全量发布和灰度发布,我直接选择全量发布,然后在模拟器看看是否成功:

这里写图片描述

状态已变成已发布了。 看看打印的log,可以看出差异包已经下载好了,重启一下就可以生效了:

这里写图片描述

这是重启后的日志,可以看出没有更新内容了,说明已是最新的补丁包:

这里写图片描述

去控制台看看有没有推送数据:

这里写图片描述
果然有推送数据(模拟器测试的一台)……

六、总结

最后这个热修复产品推送数量也是有限制的,具体多少点这里查看,给大家推荐阿里的热修复书籍,学习一下它背后的技术原理,滴滴, 车已到站,请陆续下车……