阿里云 移动热修复(Mobile Hotfix)

移动热修复

直接看效果


1.https://www.aliyun.com/product/hotfix?spm=5176.8142029.388261.233.kapzlu 

没有号的注册 有号的登录,淘宝及1688会员可直接使用会员名登录

2.android studio集成方式
gradle远程仓库依赖,打开项目找到app的build.gradle文件,添加如下配置:

添加maven仓库地址:

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

添加gradle坐标版本依赖:

compile 'com.aliyun.ams:alicloud-android-hotfix:3.2.3'

注意,若SDK集成过程中出现UTDID冲突,请参考:阿里云-移动云产品SDK UTDID冲突解决方案。https://help.aliyun.com/knowledge_detail/59152.html

3.权限说明

Sophix SDK使用到以下权限

<! -- 网络权限 -->
<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"/>

READ_EXTERNAL_STORAGE权限属于Dangerous Permissions,仅调试工具获取外部补丁需要,不影响线上发布的补丁加载,调试时请自行做好android6.0以上的运行时权限获取。

4.配置AndroidManifest文件

在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密钥" />

:App ID/App Secret将被用于计量计费,请妥善保管注意安全。

5.混淆配置

#基线包使用,生成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.**{*;}
#防止inline
-dontoptimize

6.SDK接口使用说明
6.1 接入范例

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

   private void initHotfix() {

        String appVersion;
        try {
            appVersion = this.getPackageManager().getPackageInfo(this.getPackageName(), 0).versionName;
        } catch (Exception e) {
            appVersion = "1.0.0";
        }
        // initialize必须放在attachBaseContext最前面,初始化代码直接写在Application类里面,切勿封装到其他类。
        SophixManager.getInstance().setContext(this)
                .setAppVersion(appVersion)
                .setAesKey(null)
                //.setAesKey("xxxxx")//这里如果设置了,要和补丁工具哪里要一致
                .setEnableDebug(true)
                .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","------表明补丁加载成功-----");
                        } else if (code == PatchStatus.CODE_LOAD_RELAUNCH) {
                            Log.e("TAG","-------表明新补丁生效需要重启----");
                            // 表明新补丁生效需要重启. 开发者可提示用户或者强制重启;
                        } else {
                            // 其它错误信息, 查看PatchStatus类说明
                            Log.e("TAG","-----其它错误信息------");
                        }
                    }
                }).initialize();
        // queryAndLoadNewPatch不可放在attachBaseContext 中,否则无网络权限,建议放在后面任意时刻,如onCreate中
        SophixManager.getInstance().queryAndLoadNewPatch();
    }
6.2接口说明
6.2.1 initialize方法
initialize(): <必选>
该方法主要做些必要的初始化工作以及如果本地有补丁的话会加载补丁, 但不会自动请求补丁。因此需要自行调用queryAndLoadNewPatch方法拉取补丁。这个方法调用需要尽可能的早, 必须在Application的attachBaseContext方法的最前面调用(在super.attachBaseContext之后,如果有Multidex,也需要在Multidex.install之后), initialize()方法调用之前你需要先调用如下几个方法进行一些必要的参数设置, 方法调用说明如下:
setContext(application): <必选> 
传入入口Application即可

setAppVersion(appVersion): <必选> 
应用的版本号和创建补丁的版本号要一致,不然补丁没有用

setSecretMetaData(idSecret, appSecret, rsaSecret): <可选,推荐使用> 
三个Secret分别对应AndroidManifest里面的三个,可以不在AndroidManifest设置而是用此函数来设置Secret。放到代码里面进行设置可以自定义混淆代码,更加安全,此函数的设置会覆盖AndroidManifest里面的设置,如果对应的值设为null,默认会在使用AndroidManifest里面的。

setEnableDebug(isEnabled): <可选> 
isEnabled默认为false, 是否调试模式, 调试模式下会输出日志以及不进行补丁签名校验. 线下调试此参数可以设置为true, 查看日志过滤TAG:Sophix, 同时强制不对补丁进行签名校验, 所有就算补丁未签名或者签名失败也发现可以加载成功. 但是正式发布该参数必须为false, false会对补丁做签名校验, 否则就可能存在安全漏洞风险

setAesKey(aesKey): <可选>
用户自定义aes秘钥, 会对补丁包采用对称加密。这个参数值必须是16位数字或字母的组合,是和补丁工具设置里面AES Key保持完全一致, 补丁才能正确被解密进而加载。此时平台无感知这个秘钥, 所以不用担心阿里云移动平台会利用你们的补丁做一些非法的事情。

setPatchLoadStatusStub(new PatchLoadStatusListener()): <可选> 
设置patch加载状态监听器, 该方法参数需要实现PatchLoadStatusListener接口, 接口说明见1.3.2.说明

setUnsupportedModel(modelName, sdkVersionInt):<可选> 

把不支持的设备加入黑名单,加入后不会进行热修复。modelName为该机型上Build.MODEL的值,这个值也可以通过adb shell getprop | grep ro.product.model取得。sdkVersionInt就是该机型的Android版本,也就是Build.VERSION.SDK_INT,若设为0,则对应该机型所有安卓版本。目前控制台也可以直接设置机型黑名单,更加灵活。

6.2.2 queryAndLoadNewPatch方法
该方法主要用于查询服务器是否有新的可用补丁. SDK内部限制连续两次queryAndLoadNewPatch()方法调用不能短于3s, 否则的话就会报code:19的错误码. 如果查询到可用的话, 首先下载补丁到本地, 然后
应用原本没有补丁, 那么如果当前应用的补丁是热补丁, 那么会立刻加载(不管是冷补丁还是热补丁). 如果当前应用的补丁是冷补丁, 那么需要重启生效.
应用原本没有补丁, 那么如果当前应用的补丁是热补丁, 那么会立刻加载(不管是冷补丁还是热补丁). 如果当前应用的补丁是冷补丁, 那么需要重启生效.
应用已经存在一个补丁, 请求发现有新补丁后,本次不受影响。并且在下次启动时补丁文件删除, 下载并预加载新补丁。在下下次启动时应用新补丁。
补丁在后台发布之后, 并不会主动下行推送到客户端, 需要手动调用queryAndLoadNewPatch方法查询后台补丁是否可用.
只会下载补丁版本号比当前应用存在的补丁版本号高的补丁, 比如当前应用已经下载了补丁版本号为5的补丁, 那么只有后台发布的补丁版本号>5才会重新下载.
同时1.4.0以上版本服务后台上线了“一键清除”补丁的功能, 所以如果后台点击了“一键清除”那么这个方法将会返回code:18的状态码. 此时本地补丁将会被强制清除, 同时不清除本地补丁版本号

6.2.3 killProcessSafely方法
可以在PatchLoadStatusListener监听到CODE_LOAD_RELAUNCH后在合适的时机,调用此方法杀死进程。注意,不可以直接Process.killProcess(Process.myPid())来杀进程,这样会扰乱Sophix的内部状态。因此如果需要杀死进程,建议使用这个方法,它在内部做一些适当处理后才杀死本进程。

6.2.4 cleanPatches()方法
清空本地补丁,并且不再拉取被清空的版本的补丁。正常情况下不需要开发者自己调用,因为Sophix内部会判断对补丁引发崩溃的情况进行自动清空。

6.2.5 PatchLoadStatusListener接口
该接口需要自行实现并传入initialize方法中, 补丁加载状态会回调给该接口, 参数说明如下:
mode: 无实际意义, 为了兼容老版本, 默认始终为0
code: 补丁加载状态码, 详情查看PatchStatus类说明
info: 补丁加载详细说明

handlePatchVersion: 当前处理的补丁版本号, 0:无 -1:本地补丁 其它:后台补丁

7.创建应用

登录移动热修复控制台:https://hotfix.console.aliyun.com/,点击右上角创建App,跳转到Mobile Hub App管理控制台,或者直接访问Mobile Hub控制台:https://mhub.console.aliyun.com/。

创建应用成功,点击应用


 点击 移动热修复


点击应用信息


 复制这些信息去 AndroidManifest.xml 粘贴对应   在第4点

8.生成补丁
patch补丁包生成需要使用到打补丁工具SophixPatchTool, 如还未下载打包工具,请前往下载Android打包工具。
Mac版本打包工具地址:http://ams-hotfix-repo.oss-cn-shanghai.aliyuncs.com/SophixPatchTool_macos.zip
Windows版本打包工具地址:http://ams-hotfix-repo.oss-cn-shanghai.aliyuncs.com/SophixPatchTool_windows.zip
Linux版本打包工具地址:http://ams-hotfix-repo.oss-cn-shanghai.aliyuncs.com/SophixPatchTool_linux.zip
该工具提供了Windows和macOS和Linux版本,Windows下运行SophixPatchTool.exe,macOS下运行SophixPatchTool.app,Linux下(Ubuntu 16.04 64bit最佳)运行SophixPatchTool。并且需要安装Java环境且在JDK7或以上才能正常使用。 
手机安装调试工具: 

调试工具地址:http://ams-hotfix-repo.oss-cn-shanghai.aliyuncs.com/hotfix_debug_tool-release.apk 


然后点击设置选择签名包和设置相应的密码,然后注意的是AES KEY是和application里面代码设置:.setAesKey(“xxxxxxxxxxxxxx”),值一模一样,为了解析安全设置的不一定要填,然后点击确定,在点击GO 按钮,生成patch的jar包 

9.把生成的jar上传到阿里云后台,在阿里云管理控制台,前面我们已经创建好,然后点击查看详情,


应用版本要和app的版本一致


调试补丁


调试工具用于patch正式发布前的调试环节,目前有两种测试方式:
扫码二维码方式,将刚刚上传到后台的补丁通过扫描二维码下载到本地,尝试加载补丁;
应用本地补丁方式,传入本地补丁的绝对路径,尝试加载补丁。
此方式必须确保Sophix初始化时setEnableDebug为true。出于安全考虑,我们禁止在setEnableDebug为false的包上加载本地补丁,因此setEnableDebug为false的包需要以二维码方式进行验证。

如还未下载调试工具,请下载Android调试工具,地址如下

调试工具地址:http://ams-hotfix-repo.oss-cn-shanghai.aliyuncs.com/hotfix_debug_tool-release.apk

连接测试的应用

在编辑框内输入要进行测试的应用包名,确认输入无误后点击连接应用按钮;
工具与测试的应用建立连接,连接成功后输出应用的信息;aidl方式连接原应用,所以在部分机型上可能导致失败,比如MIUI最新系统上,默认禁用了跨应用aidl,MIUI上可以设置取消这个限制,其它系统类似处理。

应用补丁

扫描二维码方式
打补丁工具生成的sophix-patch.jar补丁包上传到hotfix产品后台;
点击扫描二维码按钮,打开二维码页面,将二维码置于扫描框内;
扫描完成以后返回,输出扫描到的patch地址,向应用发出拉取patch的请求;

patch拉取和加载状态在输出台输出,当显示下载和加载成功,打开应用进行检查。

应用本地补丁方式
打补丁工具生成的sophix-patch.jar补丁包推送到本地存储任何一个目录下;
应用本地补丁按钮上面的输入框输入补丁在手机存储中的绝对路径;

补丁加载状态在输出台输出,当显示下载和加载成功,打开应用进行检查

断开连接的应用

点击断开应用连接按钮,将断开与应用的连接。调试到此结束。

清除通知内容

当输出台显示信息过多时,可点击清除下列通知内容按钮对通知信息进行清除。

使用示例


下载demo工程后, 安装并打开old.apk, 安装调试工具;

输入"com.example.demo"包名, 连接应用, 提示连接成功;

补丁工具生成的补丁包sophix-patch.jar推送到本地的/sdcard/Download目录, 然后输入该补丁包的绝对路径, 点击应用本地补丁按钮;
Mode:2 表示本地补丁模式, Code:1 表示加载成功 HandlePatchVersion:-1 表示本地补

扫描二维码示例

补丁工具生成的补丁包sophix-patch.jar上传到hotfix控制台;
点击扫描二维码按钮扫后台补丁二维码;

Mode:1 表示扫码模式, Code:12 表示应用当前已经有一个补丁, 所以新补丁不会立刻加载需要等下一次重启加载, HandlePatchVersion:89 表示后台拉取下来的补丁版本89。


阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页