阿里热修复Sophix的使用指南

"我正在参加「掘金·启航计划」" 这是我的第4篇文章

一、阿里云热修复Sophix的介绍

1.1、首先看一下市场上热修复方案的比较,如下图 原文:help.aliyun.com/document_de…

image.png

1.2、收费情况 原文:help.aliyun.com/document_de…

image.png

二、接入指南

2.1、准备

  1. 准备好阿里云账号
  2. 进行身份实名认证
  3. 移动研发平台EMAS,进行项目创建,创建后会生成一个aliyun-emas-services.json 文件,里面包含了热修复sdk接入时所需的密钥,很重要

2.2、EMAS平台的添加流程如下:

2.2.1、添加应用

image.png

image.png

生成应用的key信息文件,如果建议按需接入所需功能,没必要也不安全,按下图将文件放入到app中
image.png

下图的红框中的添加sdk也是,添加emas平台中的所有功能,建议按需接入某个功能(如:热修),另外该插件在Android gradle 7之上会报错
image.png

2.3、热修复接入 原文:help.aliyun.com/document_de…

注意点如下:

  • 使用gradle plugin版本高于4.2时,可能会自动开启资源优化。开启资源优化后,资源名称被混淆,会导致补丁工具在生成补丁时一直卡在”开始构建补丁…..”,无法正常解析apk包。解决方案:在gradle.properties 中新增android.enableResourceOptimizations=false,重新生成基线包和修复包,然后再生成补丁。
  • 密钥的使用推荐在SophixStubApplication 中初始化,而不是在AndroidManifest文件中配置
  • 使用android studio打包生成apk时,要关闭instant run。
  • queryAndLoadNewPatch方法用来请求控制台发布的补丁包,会涉及设备信息读取,所以必须在用户同意隐私协议之后调用。另外用户可根据业务情况,酌情考虑是否打开此开关。
  • 但不可放在attachBaseContext中,否则无网络权限,建议放在主进程用户同意隐私协议之后的任意时刻。

接入流程步骤如下:

添加工程依赖

1. Android Studio集成方式

gradle远程仓库依赖, 打开项目找到App的build.gradle文件,添加如下配置:


添加Maven仓库地址:



****

```
repositories {
   maven {
       url "http://maven.aliyun.com/nexus/content/repositories/releases"
   }
}
```

2.添加gradle坐标版本依赖:

android {
    ......
    defaultConfig {
        applicationId "com.xxx.xxx" //包名
        ......
        ndk {
            //选择要添加的对应cpu类型的.so库。
            //热修复支持五种
            abiFilters 'arm64-v8a', 'armeabi', 'armeabi-v7a', 'x86', 'x86_64'
        }
        ......
    }
    ......
}
dependencies {
    ......
        compile 'com.aliyun.ams:alicloud-android-hotfix:3.3.5'
    ......
}

3.添加应用权限

Sophix SDK使用到以下权限,使用Maven依赖或者aar依赖可以不用配置。具体配置在AndroidManifest.xml中。

<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" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

4.配置AndroidManifest文件,

也可以不用配置(直接在SophixStubApplication,文件中初始化配置即可(推荐在SophixStubApplication中配置)),在 移动研发平台EMAS,进行项目创建,创建后会生成一个aliyun-emas-services.json 文件,里面包含了热修复sdk接入时所需的密钥

AndroidManifest.xml中间的application节点下添加如下配置:

<meta-data
android:name="com.taobao.android.hotfix.IDSECRET"
android:value="App ID" />
<meta-data
android:name="com.taobao.android.hotfix.APPSECRET"
android:value="App Secret" />
<meta-data
android:name="com.taobao.android.hotfix.RSASECRET"
android:value="RSA密钥" />

5. 混淆配置,按需配置

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


开启混淆时,生成修复包要使用旧包的mapping文件以保证混淆结果一致。
初始化

6. 初始化

初始化的调用应该尽可能的早,必须在Application.attachBaseContext()的最开始(在super.attachBaseContext之后,如果有Multidex,也需要在Multidex.install之后)进行SDK初始化操作,初始化之前不能用到其他自定义类,否则极有可能导致崩溃。而查询服务器是否有可用补丁的操作可以在后面的任意地方。不建议在Application.onCreate()中初始化,因为如果带有ContentProvider,就会使得Sophix初始化时机太迟从而引发问题。

Sophix最新版本引入了新的初始化方式。

原来的初始化方式仍然可以使用。只是新方式可以提供更全面的功能修复支持,将会带来以下优点:

  • 初始化与应用原先业务代码完全隔离,使得原先真正的Application可以修复,并且减少了补丁预加载时间等等。
  • 新方式能够更完美地兼容Android 8.0以后版本。
public class SophixStubApplication extends SophixApplication {
    private final String TAG = "SophixStubApplication";
    String appVersion = "0.0.0";



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

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        initSophix();
    }


    private void initSophix() {
        try {
            appVersion = this.getPackageManager()
                    .getPackageInfo(this.getPackageName(), 0)
                    .versionName;
        } catch (Exception e) {
        }
        final SophixManager instance = SophixManager.getInstance();
        List<String> tags = new ArrayList<>();
        ///todo 构建正式包之前需要修改为:
        ///tags.add("production");
        tags.add("test"); //这个值就是,你进行灰度包热修时,要填写的tag
        for (String tag : tags) {
            Log.e(TAG, "sophix tag:" + tag);
        }
        instance.setContext(this)
                .setAppVersion(appVersion)
                .setEnableDebug(false)
                .setEnableFullLog()
                .setTags(tags)
                .setSecretMetaData("你自己的hotfix.idSecret",
                        "你自己的emas.appSecret",
                        "你自己的hotfix.rsaSecret")
                .setPatchLoadStatusStub(new PatchLoadStatusListener() {
                    @Override
                    public void onLoad(final int mode, final int code, final String info, final int handlePatchVersion) {
                        Log.e(TAG, "sophix handlePatchVersion:" + handlePatchVersion + " /code:" + code + " /info:" + info);
                        if (code == PatchStatus.CODE_LOAD_SUCCESS) {
                            ///重启后会装载补丁会调用该方法
                            Log.e(TAG, "sophix load patch " + handlePatchVersion + " success!" + info);
                        } else if (code == PatchStatus.CODE_LOAD_RELAUNCH) {
                            ///补丁加载成功会调用该方法
                            // 如果需要在后台重启,建议此处用SharePreference保存状态。
                            Log.e(TAG, "sophix preload patch success. restart app to make effect. handlePatchVersion:" + handlePatchVersion);
                          
                            Intent intent = new Intent();
                            intent.putExtra("message", "恭喜你,成功接收到发送的广播" + PatchStatus.CODE_LOAD_RELAUNCH);
                            intent.setAction("可使用重启广播重启");
                            sendBroadcast(intent);
                        }
                    }
                }).initialize();
    }

}

7.最后,需要把AndroidManifest里面的application改为这个新增的SophixStubApplication类:

    <application
        android:name="com.my.pkg.SophixStubApplication"
        ... ...>
        ... ...

这样便完成了新方式的初始化接入改造。

三、热修复打差量包流程 热修控制台地址:emas.console.aliyun.com/service/dev…

3.1、找到热修界面添加应用

如下图:注意应用版本必须与你的versionName一致,否则会导致后续下发查找不到差量包

image.png

image.png

3.2、打差量包 原文:help.aliyun.com/document_de…

  1. 准备好SophixPatchTool_windows打包工具各版本打包工具如下:
  1. 打一个release的包
  2. 再第2步的release包的基础上修改一些内容,在打一个release包
  3. 利用工具开始打包,如下图

注意: 每次热修差量包的生成的基础包就是你上次发版后的包,并不是说你在进行第三次热修时,用第二次的热修包,作为基准包

问题包:1.0-querelease-2022-12-07.apk,修复包:1.0-release-2022-12-07.apk

image.png

打开工具:

image.png

选择两个包填充

image.png

选择设置填好keystore

image.png

选择高级,默认如下图,强制冷启动就是补丁包下发后必须重启,建议勾选强制冷启动,为何:看下面解释

image.png

Sophix何时走即时生效热修复,何时走冷启动修复?
原文:help.aliyun.com/document_de…

配置完成后点击Go开始打差量包

image.png

成功

image.png

sophix-patch.jar 就是打出的差量包
image.png

四、上传补丁-发布

4.1、添加你的应用版本,然后上传补丁

image.png

4.2、发布补丁 原文:help.aliyun.com/document_de…

上传后点击发布如下图

image.png

下载[hotfixdebug]工具验证你的补丁包是否成功,调试流程原文如下链接:help.aliyun.com/document_de…

image.png

调试没问题后点击上图的新建发布

image.png

发布的话:有全量,灰度两种,灰度的话 ,需要设置指定标签tag,就是你的应用app中Sophix所配置的,如下图:(推荐是全量)

image.png

4.3、发布成功后在app中调用查询补丁方法SophixManager.getInstance().queryAndLoadNewPatch()

后续将回调PatchLoadStatusListener如下图

image.png

依次出现热修状态码如下:状态码含义:help.aliyun.com/document_de…

image.png

image.png上图加载成功后提示需要重启后热修生效

五、测试用例

1. 修改一个toast文案,然后修复成功。

2. 修改一张图片,增加一张新的图片进行展示,增加点击效果,增加一个新的类生成提示文案(mipmap-hdpi、drawable-xhdpi、drawable、都添加图片)

drawable-xhdpi 中新增热修图片添加可能会存在问题:如下,然后按要求在drawable 中添加后,热修成功。help.aliyun.com/document_de…
image.png

3. 添加assets文件,热修成功。
4. 四大组件不行,因为需要在AndroidManifest.xml文件中配置,热修的时候使用的话会报找不到的,需要注册异常,如下图

image.png

5. 删除测试4中的组件跳转流程,热修测试成功,

6. 删除测试2中添加的xml中的代码与相关资源,热修测试成功

注意:
1.热修包存在的话,每杀死app,初始化进来都会走

onLoad方法的回调


code == PatchStatus.CODE_LOAD_SUCCESS



image.png

2.同一个热修包,设置不同的tag,然后点击下发的话都会下发一次

3.清除热修包后,之前发布的版本都无效了,再次查询加载,都查不到了,只能之后在这个版本重新发布

SophixManager.getInstance().cleanPatches()

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYebQw43' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片