阿里百川HotFix的接入步骤,阿里百川HotFix的简单

作者:计算机网络

在Application的onCreate里完成初始化工作。

上传补丁

阿里百川HotFix简单实践(1)0006.jpg

关于灰度发布的说明,感觉上这个地方很有意思,实际上测试存在很多种,AB,灰度等等.
百川的灰度是完全的随机,并不是想象的可以基于Android版本或者品牌来操作.
臆测这种完全的随机才能体现真正的补丁到达率.

四、android studio的接入

1,添加gradle坐标版本依赖:

dependencies {
compile 'com.taobao.android:alisdk-hotfix:1.4.0'
}

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

repositories {
maven {
url
"http://repo.baichuan-android.taobao.com/content/groups/BaichuanRepositories"
}
flatDir { dirs 'libs'}
}


注意事项:
1.1,1.4.0版本会传递性依赖utdid这个sdk, 所以不需要重复依赖.但是另一方面其它阿里系SDK也可能依赖了utdid这个SDK, 如果编译期间报utdid重复, 所以此时进行如下处理即可, 关闭传递性依赖:

compile ('com.taobao.android:alisdk-hotfix:1.4.0') {
transitive = false
}

2.1,如若仓库访问失败, 那么用本地依赖的方式进行依赖, SDK下载见“1.1 Android SDK及工具下载”节, 首先复制下载SDK文件夹下的.aar和.jar到libs目录下, 然后更新模块下的build.gradle文件

repositories {
...
flatDir {
dirs 'libs'
}
}
dependencies {
compile files('libs/utdid4all-1.1.5.3_proguard.jar')
compile(name:'alisdk-hotfix-1.4.0', ext:'aar')
}


3,HotFix 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"/>

4, 配置AndroidManifest文件
在AndroidManifest.xml中间的application节点下添加如下配置:

<meta-data android:name="com.taobao.android.hotfix.APPKEY" android:value="your-app-key" />
<meta-data
android:name="com.taobao.android.hotfix.APPSECRET"
android:value="your-app-secret" />
<meta-data
android:name="com.taobao.android.hotfix.RSASECRET"
android:value="your-rsa-secret" />

4.1,获取APPKEY,APPSECRET,RSASECRET
4.1.1,选择你要使用的应用

图片 1

Paste_Image.png

4.1.2,这里就得到了AppKey和AppSecret

图片 2

Paste_Image.png

图片 3

Paste_Image.png

4.1.3,点击阿里百川HotFix,就进入到下面的这个界面

图片 4

Paste_Image.png

在这个页面,选择你要用的应用,有android和ios,选择管理,appID也是在这里获取的,下面我们会用到

图片 5

Paste_Image.png

1.2.1 android studio集成方式

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

添加maven仓库地址:

repositories {

  maven {

  url"http://maven.aliyun.com/nexus/content/repositories/relea  ses"

 }

}

添加gradle坐标版本依赖:

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

注意,若SDK集成过程中出现UTDID冲突,请参考:阿l里云-移动云产品SDK UTDID冲突解决方案。

如若仓库访问失败, 那么用本地依赖的方式进行依赖, SDK下载见“1.5 客户端本地SDK及DEMO下载”节。

这里需要特别注意的一点:关于SophixManager.getInstance().queryAndLoadNewPatch();

附链接

http://baichuan.taobao.com/docs/doc.htm?spm=a3c0d.7629140.0.0.IJz6Sj&treeId=234&articleId=105457&docType=1

七、上传补丁

图片 6

Paste_Image.png

1,没有就选择新增版,注意这个地方必须与app端的versionName一致,建好后,选择 查看详情

图片 7

Paste_Image.png

2,选择上传补丁,这样就基本成功啦

详细的文档请参考官方文档:http://baichuan.taobao.com/docs/doc.htm?spm=a3c0d.7629140.0.0.1ZqGRF&treeId=234&articleId=105457&docType=1

1.3.2.3 killProcessSafely方法

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

通过下载的比较工具 对比某一相同版本的新旧包。最后生成差异包baichuan-hotfix-patch.jar。

生成patch

参数说明

-c, -cmd: 值为patch: 打补丁命令 值为help: 查看使用说明
-s, -src_apk:填写本地的原始APK(有问题的APK). 必选
-f, -fixed_apk:已经修复过该问题APK. 必选
-w, -wp:输出patch的路径, 最后如果打补丁成功会在wp目录下自动创建的hotfix-working目录生成baichuan-hotfix-patch.jar补丁文件. 必选
-k, -sign_file_url:本地的签名文件的路径,不输入则不做签名. 可选
-p, -sign_file_pass: 证书文件的密码, 可选
-a, -sign_alias: 证书的别名. 可选
-e, -sign_alias_pass: 证书别名的密码. 可选
-l, -filterClassFilePath:本地的白名单类列表文件的路径,放进去的类不会再计算patch,文件格式: 一行一个类名. 可选

demo示例

java -jar BCFixPatchTools-1.3.0.jar -c patch -s old.apk -f new.apk -w patch-out -k test.keystore -p test123 -a test123 -e test123 -l filterClass.txt

filterClass.txt文件内容如下: 表示A类和B类不会比较在新旧apk中的差异直接过滤.
最后baichuan-hotfix-patch.jar补丁文件在patch-out/hotfix-working目录

补丁包的生成有一些细节需要注意,特别强调按照官方文档操作
再次强调版本号的问题,新旧项目版本号一致
如果生成过程提示JniLibs不存在,可做如下操作

jni.png

一、注册阿里百川账号

1,如果有淘宝账号可以直接登陆,没有就申请
2,申请开发者(有个人开发者和企业开发者)

1.2.2 eclipse集成方式

下载OneSDk.zip,解压出hotfix_core-release.aar文件后再解压这个aar文件

复制解压文件jni目录下的libsophix.so到自己的jni目录下, eclipse jni目录一般指的就是项目libs目录

复制utdid4all-1.1.5.3_proguard.jar和alicloud-android-utils-1.0.3.jar文件到项目libs目录下

重命名classes.jar为sophix.jar并复制到项目libs目录下

合并AndroidManifest.xml文件中的内容到本项目AndroidManifest.xml文件

编译期间报utdid类重复异常, 那么步骤2中添加的utdid4all-1.1.5.3_proguard.jar从项目libs目录移除即可

图片 8创建应用图片 9minifest文件配置图片 10权限

关于混淆

现在有了各种加固方式混淆的意义没有当时那么重要,实际上混淆的另一个意义是瘦身,百川对于混淆这个地方有特别的说明。

-keep class * extends java.lang.annotation.Annotation
-keepclasseswithmembernames class * {
    native <methods>;
}
-keep class com.alipay.euler.andfix.**{
    *;
}
-keep class com.taobao.hotfix.aidl.**{*;}
-keep class com.ta.utdid2.device.**{*;}
-keep class com.taobao.hotfix.HotFixManager{
    public *;
}

---------------总结分割线------------

项目中目前集成了热修复,但并未使用,如之前所说的在技术选型上的考虑(红色标注的地方),当然各家公司需求也不一样,可斟酌选择.阿里百川较容易的实现了热修复功能,有些高级用法还是要参见官方文档和Demo

五、SDK的使用范例

一般我们都写在Application:

    public static String appVersion;   
    public static String appId;    
   @Override  
  public void onCreate() {       
       super.onCreate();       
       initApp();       
       initHotfix();  
  }
private void initApp() {  
    this.appId = "82875-1"; //替换掉自己应用的appId   
    try {        
     this.appVersion = this.getPackageManager().getPackageInfo(this.getPackageName(), 0).versionName;  
      } catch (Exception e) {       
         this.appVersion = "1.0.0";   
 }}
/** * 建议在Application.onCreate方法中执行initialize和queryNewHotPatch操作, 
尽可能早的执行 * 本demo只是为了测试的方便, 所以把这两个操作放在了Activity中 */
private void initHotfix() {   
   //此处不再需要调用queryNewHotPatch方法, initialize方法内部会调用queryNewHotPatch方法.                        
       HotFixManager.getInstance().setContext(this)          
                                  .setAppVersion(appVersion)          
                                  .setAppId(appId)         
                                  .setAesKey(null)          
                                  .setSupportHotpatch(true)      
                                  .setEnableDebug(true)         
                                  .setPatchLoadStatusStub(new PatchLoadStatusListener() {     
                @Override               
     public void onload(final int mode, final int code, final String info, final int handlePatchVersion) {     
               // 补丁加载回调通知                
                 if (code == PatchStatusCode.CODE_SUCCESS_LOAD) {              
                                Log.e("TAG","--------更新成功---------->");                     
                                // TODO: 10/24/16 表明补丁加载成功                
                         } else if (code == PatchStatusCode.CODE_ERROR_NEEDRESTART) {       
                              Log.e("TAG","--------更新错误---------->");                     
                           // TODO: 10/24/16 表明新补丁生效需要重启. 
业务方可自行实现逻辑, 提示用户或者强制重启, 建议: 用户可以监听进入后台事件, 然后应用自杀           
                                    } else if (code == PatchStatusCode.CODE_ERROR_INNERENGINEFAIL) {     
                                    Log.e("TAG","--------清空---------->");                    
                      // 内部引擎加载异常, 推荐此时清空本地补丁, 但是不清空本地版本号, 防止失败补丁重复加载                        
                 HotFixManager.getInstance().cleanPatches(false);              
                                               } else {                 
                        Log.e("TAG","--------其他---------->");                
                           // TODO: 10/25/16 其它错误信息, 查看PatchStatusCode类说明            
                                                  }       
                        }    
        }).initialize();}

前言

最近刚刚学习了一波热更新技术,之前也打算去研究的,当时看了鸿洋大神博客里对热修复Tinker的讲解,看的不是很懂,看完后也没有动手去实现,就不了了之。这两天又有兴趣研究了一下,对比了当前一些比较流行的热更新技术之后,发现市场上口碑比较好的有阿里巴巴旗下的Sophix热更新方案和腾讯的 Tinker热更新方案,然后自己实现了一遍Sophix方案,个人感觉比较容易实现。下面来介绍一下具体操作。

Sophix --阿里终极热修复方案

下面就来介绍项目集成下看看具体的使用效果:

快速集成

这里需要注意的地方是传递性依赖utdid这个sdk, 所以不需要重复依赖utdid.但是另一方面其它阿里系SDK也可能依赖了utdid这个SDK, 如果编译期间报utdid重复, 所以此时进行如下处理即可, 关闭传递性依赖:

3.初始化

初始化 2016-11-28 下午5.41.19.png

六、生成补丁

更新补丁之后是这样的

图片 11

image.png

图片 12

image.png

首先我们去下载补丁打包工具(不得不说,工具确实比较粗糙(丑)。。。)

图片 13

image

旧包:<必填> 选择基线包路径(有问题的 APK)。

新包:<必填> 选择新包路径(修复过该问题 APK)。

日志:打开日志输出窗口。

高级:展开高级选项

设置:配置其他信息。

GO!:开始生成补丁。

所以首先我们把旧包和新包添加上之后,配置好之后看看会发生什么吧!

强制冷启动是补丁打完后重启才生效。

图片 14

image

图片 15

image

图片 16

image

时间看情况吧,因为项目本身内容比较少,所以生成补丁的速度比较快,等一下就好了。项目比较大的话估计需要等的时间长一点

我们来看看到底生成了什么?打开补丁生成目录

图片 17

image

这个就是我们生成的补丁文件了,下一步补丁如何使用?

我们打开阿里的管理控制台,将补丁上传到控制台,就可以发布了.

图片 18

image.png

图片 19

image.png

我们首先下载调试工具来看看效果吧,首先连接应用(我用了真机和模拟器都没有出现过问题)

图片 20

image.png

然后有两种方式可以加载补丁包,一种是扫二维码,还有一种是加载本地补丁jar包,这个模拟器不方便操作,我用的真机调试的

图片 21

image.png

从图中的 log 提示我们可以看出首先下载了补丁包,然后打补丁完成,要求我们重启 APP,那我们就重启呗,看到的当然就应该是补丁打好的 1.0.1 版本和 Toast 弹出正常啦!!(这里有个坑,在阿里云的管理控制台,补丁需要与对应的版本进行更新,比如最新应用版本为1.0,你就在1.0版本上添加补丁,而不要在1.0.1版本上添加补丁,否则应用会找不到需要更新的补丁)

图片 22

image.png

图片 23

image.png

当然了,目前我们还是在调试工具上加载的补丁包,我们接下来将补丁包发布后就可以不用调试工具,直接打开 app 就可以实现打补丁了,这样就完成了 bug 的修复!

其实这么看起来确实是非常简单就实现了热修复,主要我们的生成补丁工作都是交给阿里提供的工具实现了,其实我们也能看得出来,Sophix 和前面介绍的 AndFix 很像,不同的地方是补丁文件已经给出工具可以一键生成了,而且支持的东西更多了。其他比如 so 库和 library 以及资源文件的更新大家可以查看官方文档了解。

工具下载地址baichuan.taobao.com/docs/doc.htm

这是在公司做的一个关于热修复的技术分享

是刚推出的时候就关注的.其中的一些问题和经验写在前面,其中也有使用上的谬误,关于版本号的理解,后来咨询@悟二解决的.由于当初做的是ppt现在转换成图片格式.
若有不足之处,欢迎拍砖.

 实际使用的总结
1.version name  应该和原项目一致
2.同一台手机加载成功后,卸载再安装统计上只会出现一次
3.未安装app的手机第一次安装,patch即会打入进去
4.在测试中三星手机到达率要低于其他的手机
5.dagger rxjava 项目中都有使用,修改方法补丁也可顺利到达

阿里百川HotFix简单实践(1)0000.jpg

阿里百川HotFix简单实践(1)0001.jpg

阿里百川HotFix简单实践(1)0002.jpg

阿里百川HotFix简单实践(1)0003.jpg

备注此处是最新的依赖

添加maven仓库地址:

repositories {   
maven {      
url "http://repo.baichuan-android.taobao.com/content/groups/public/"  
  }
}

添加gradle坐标版本依赖:
dependencies {
compile 'com.alibaba.sdk.android.plugins:alisdk-hotfix:1.3.3'
compile 'com.alibaba.sdk.android.plugins.jar:alisdk-utdid:0.0.1'
}

特别说明
如果编译期间报utdid类重复异常,
那么应该是其它阿里系SDK也依赖了utdid这个SDK, 此时去掉
compile'com.alibaba.sdk.android.plugins.jar:alisdk-utdid:0.0.1'
现在项目中集成了友盟统计,出现了这个问题

一)先看工程

图片 24

Paste_Image.png

1,我在该目录下创建了一个patchtool_demo的文件夹,里面放了一个BCFixPatchTools-XXX.jar,如果没有该架包,请去官方网站下载,如果没有找到,它的官方demo里面有

图片 25

Paste_Image.png

2,这两个apk,old.apk是修改前的,new.apk是修改后的,这里的apk最好不要用运行时的apk

1.3.2.2 queryAndLoadNewPatch方法

该方法主要用于查询服务器是否有新的可用补丁. SDK内部限制连续两次queryAndLoadNewPatch()方法调用不能短于3s, 否则的话就会报code:19的错误码. 如果查询到可用的话, 首先下载补丁到本地, 然后

应用原本没有补丁, 那么如果当前应用的补丁是热补丁, 那么会立刻加载(不管是冷补丁还是热补丁). 如果当前应用的补丁是冷补丁, 那么需要重启生效.

应用已经存在一个补丁, 请求发现有新补丁后,本次不受影响。并且在下次启动时补丁文件删除, 下载并预加载新补丁。在下下次启动时应用新补丁。

补丁在后台发布之后, 并不会主动下行推送到客户端, 需要手动调用queryAndLoadNewPatch方法查询后台补丁是否可用.

只会下载补丁版本号比当前应用存在的补丁版本号高的补丁, 比如当前应用已经下载了补丁版本号为5的补丁, 那么只有后台发布的补丁版本号>5才会重新下载.

同时1.4.0以上版本服务后台上线了“一键清除”补丁的功能, 所以如果后台点击了“一键清除”那么这个方法将会返回code:18的状态码. 此时本地补丁将会被强制清除, 同时不清除本地补丁版本号

说说这些天集成Sophix在项目中遇到的坑:

特别的说明关于SO库的处理

当前项目集成了高德地图,按照官方文档操作操作即可,以下为特别的说明

不管是android studio/eclipse集成方式都务必做如下检查! 否则将抛UnsatisfiedLinkError异常导致补丁加载失败

检查当前项目结构jniLibs中是否有armeabi-v7a, arm64-v8a目录, 如果有: 请复制下载SDK(SDK下载&版本更新记录里“SDK”项下载下来, 然后解压)文件夹中armeabi-v7a/arm64-v8a目录下对应的so文件到对应的文件夹下面. 如果没有armeabi-v7a/arm64-v8a目录, 则不需要做这个处理。
PS:hotfix这样处理的目的: 减少jar包大小进而减少apk大小. 所以alisdk-hotfix-**.aar中只有armeabi下的libandfix.so文件, 所以如果当前项目目录下有armeabi-v7a/arm64-v8a目录, 但是没有复制对应的libandfix.so文件进去, 那么在相应cpu架构的机型下加载libandfix.so就会报找不到so文件的异常(UnsatisfiedLinkError)
如果做了上述处理仍然发现UnsatisfiedLinkError异常, 那么请确保是否是打包引起的问题, 解压apk, 看libs下armeabi-v7a/arm64-v8a目录是否有对应的libandfix.so文件

三、申请产品权限

图片 26

Paste_Image.png

1.3.1 接入范例

initialize的调用应该尽可能的早,必须在Application.attachBaseContext()或者Application.onCreate()的最开始进行SDK初始化操作,初始化之前不能用到其他自定义类,否则极有可能导致崩溃。而查询服务器是否有可用补丁的操作可以在后面的任意地方。

// initialize最好放在attachBaseContext最前面,初始化直接在Application类里面,切勿封装到其他类

SophixManager.getInstance().setContext(this)

            .setAppVersion(appVersion)

            .setAesKey(null)

            .setEnableDebug(true)

            .setPatchLoadStatusStub(new PatchLoadStatusListener() {

                @Override

                public voidonLoad(final int mode, final int code, final String info, final int handlePatchVersion) {

                    // 补丁加载回调通知

                    if (code== PatchStatus.CODE_LOAD_SUCCESS) {

                        // 表明补丁加载成功

                    } else if (code== PatchStatus.CODE_LOAD_RELAUNCH) {

                        // 表明新补丁生效需要重启. 开发者可提示用户或者强制重启;

                        // 建议: 用户可以监听进入后台事件, 然后调用killProcessSafely自杀,以此加快应用补丁,详见1.3.2.3

                    } else {

                        // 其它错误信息, 查看PatchStatus类说明

                    }

                }

            }).initialize();

// queryAndLoadNewPatch不可放在attachBaseContext 中,否则无网络权限,建议放在后面任意时刻,如onCreate中

SophixManager.getInstance().queryAndLoadNewPatch();

首先在阿里百川hotfix官方地址创建对应的App,并把生成的 App ID、App Secret、RSA密钥在AndroidManifest.xml里配置一下。

使用测试工具

补丁顺利下拉,接下来应该是皆大欢喜的结局,然而.....
verifyApk.failed

阿里百川HotFix简单实践(1)0007.png

阿里百川HotFix简单实践(1)0008.jpg

李四他爹不知不觉成了老王!!!

补丁结果图片.png

二)怎么生成baichuan-hotfix-patch.jar

1,在patchtool_demo 下运行cmd命令
2,参数说明

  • -c, -cmd: 值为patch: 打补丁命令 值为help: 查看使用说明
  • -s, -src_apk:填写本地的原始APK(有问题的APK). 必选
  • -f, -fixed_apk:已经修复过该问题APK. 必选
  • -w, -wp:输出patch的路径, 最后如果打补丁成功会在wp目录下自动创建的hotfix-working目录生成baichuan-hotfix-patch.jar补丁文件. 必选
  • -k, -sign_file_url:本地的签名文件的路径,不输入则不做签名. 可选
  • -p, -sign_file_pass: 证书文件的密码, 可选
  • -a, -sign_alias: 证书的别名. 可选
  • -e, -sign_alias_pass: 证书别名的密码. 可选
  • -y, -aes_key: 自定义aes秘钥, 必须是16位. 可选
  • -l, -filterClassFilePath:本地的白名单类列表文件的路径,放进去的类不会再计算patch,文件格式: 一行一个类名. 可选
    3,命令例子示范:

java -jar BCFixPatchTools-1.3.0.jar -c patch -s old.apk -f new .apk -w patch-out -k test.keystore -p test123 -a test123 -e test123 -y 1234567891234567 -l filterClass.txt

最终就会生成一个patch-out文件夹,补丁就在该文件夹下

图片 27

Paste_Image.png

1.6 注意事项

发布前请严格按照:扫码内测 => 灰度发布 => 全量发布的流程进行,以保证补丁包能够正常在所有Android版本的机型上生效。为了保险起见,理论上应该对每个版本的android手机都测一遍是否生效会比较好。不过,其实只需测试通过以下具有代表性的Android版本就基本没什么大问题了:4.0、4.4、5.1、7.0

遇到问题先查看文档:https://help.aliyun.com/knowledge_list/51422.html

ii:当然了,除了这个问题,如果在热修复了一些res或者so文件而且在比较差异包的时候,未勾选强制冷启动,那么也会导致这个NoClassDefFoundError异常。而且会一直crash,直到下个补丁包修复该问题。所以说,安全起见,在比较差异包的时候最好还是强制要求冷启动,这样可以提升安全系数。

二、创建百川应用

1,如果您已经创建过百川应用,可以直接在指定应用上使用HotFix产品。
2,如果您尚未创建过百川应用,点击创建应用

图片 28

Paste_Image.png

1.2.4 配置AndroidManifest文件

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

android:name="com.taobao.android.hotfix.IDSECRET"

android:value="App ID" />

android:name="com.taobao.android.hotfix.APPSECRET"

android:value="App Secret" />

android:name="com.taobao.android.hotfix.RSASECRET"

android:value="RSA密钥" />

将上述value中的值分别改为通过平台HotFix服务申请得到的App Secret和RSA密钥,出于安全考虑,建议使用setSecretMetaData这个方法进行设置,详见1.3.2.1的方法说明。

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

先来看一组市面上的几款热修复对比图:

1.3.2.4 cleanPatches()方法]

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

4.热修复的测试工具扫码不准,经常提示错误信息:请检查AppSecret。 但实际上这些配置参数都是正确的,多次尝试后才能加载补丁包成功,因为这个测试要花费很久,非常影响测试效率。

1.3.2.1 initialize方法

initialize(): <必选>

该方法主要做些必要的初始化工作以及如果本地有补丁的话会加载补丁, 但不会自动请求补丁。因此需要自行调用queryAndLoadNewPatch方法拉取补丁。这个方法调用需要尽可能的早, 推荐在Application的onCreate方法中调用, 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.2说明

setUnsupportedModel(modelName, sdkVersionInt):<可选> 把不支持的设备加入黑名单,加入后不会进行热修复。modelName为该机型上Build.MODEL的值,这个值也可以通过adb shell getprop | grep ro.product.model取得。sdkVersionInt就是该机型的Android版本,也就是Build.VERSION.SDK_INT,若设为0,则对应该机型所有安卓版本。

图片 29混淆代码

1.2 集成准备

登录阿里百川hotfix管理后台,上传补丁包baichuan-hotfix-patch.jar。分别进行扫码测试、灰度发布、全量发布三个流程。

1.3 SDK接口使用说明

我们可以看看阿里系的新旧热修复对比图:

1.4 版本管理说明

说明一:patch是针对客户端具体某个版本的,patch和具体版本绑定

eg. 应用当前版本号是1.1.0, 那么只能在后台查询到1.1.0版本对应发布的补丁, 而查询不到之前1.0.0旧版本发布的补丁.

说明二:针对某个具体版本发布的新补丁, 必须包含所有的bugfix, 而不能依赖补丁递增修复的方式, 因为应用仅可能加载一个补丁

eg. 针对1.0.0版本在后台发布了一个补丁版本号为1的补丁修复了bug1, 然后发现此时针对这个版本补丁1修复的不完全, 代码还有bug2, 在后台重新发布一个补丁版本号为2的补丁, 那么此时补丁2就必须同时包含bug1和bug2的修复才行, 而不是只包含bug2的修复(bug1就没被修复了)

3.差异包过大的问题。一个很小的改动,动辄几M,对于项目团队来说,耗费流量这一点很难接受。

1.1Android SDK及工具下载

阿里云Sophix 3.0版本现已上线!

Sophix提供了一套更加完美的客户端服务端一体的热更新方案,做到了图形界面一键打包、加密传输、签名校验和服务端控制发布与灰度功能,让你用最少的时间实现最强大可靠的全方位热更新。

一张表格来说明一下各个版本热修复的差别:

图片 30

image

说明:

[0] 部分情况指的是构造方法、参数数目大于8或者参数包括long,double,float基本类型的方法。

[1] 冷启动方式,指的是需要重启app在下次启动时才能生效。

[2] 对于Andfix及Hotfix 1.X能够支持的代码变动情况,都能做到即时生效。而对于其他代码变动较大的情况,会走冷启动方式,此时就无法做到即时生效。

[3] Hotfix 1.X已经支持绝大部分主流手机,只是在X86设备以及修改了虚拟机底层结构的ROM上不支持。

[4] 由于支持了资源和库,如果有这些方面的更新,就会导致的补丁变大一些,这个是很正常的。并且由于只包含差异的部分,所以补丁已经是最大程度的小了。

[5] 提供服务端的补丁发布和停发、版本控制和灰度功能,存储开发者上传的补丁包。

i:拉取补丁的代码 不要放置在application中,否则会报异常: java.lang.NoClassDefFoundError;

1.3.2.5 PatchLoadStatusListener接口

该接口需要自行实现并传入initialize方法中, 补丁加载状态会回调给该接口, 参数说明如下:

mode: 无实际意义, 为了兼容老版本, 默认始终为0

code: 补丁加载状态码, 详情查看PatchStatus类说明

info: 补丁加载详细说明

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

常见状态码说明如下: 一个补丁的加载一般分为三个阶段: 查询/预加载/加载

//兼容老版本的code说明

int CODE_LOAD_SUCCESS = 1;//加载阶段, 成功

int CODE_ERR_INBLACKLIST = 4;//加载阶段, 失败设备不支持

int CODE_REQ_NOUPDATE = 6;//查询阶段, 没有发布新补丁

int CODE_REQ_NOTNEWEST = 7;//查询阶段, 补丁不是最新的

int CODE_DOWNLOAD_SUCCESS = 9;//查询阶段, 补丁下载成功

int CODE_DOWNLOAD_BROKEN = 10;//查询阶段, 补丁文件损坏下载失败

int CODE_UNZIP_FAIL = 11;//查询阶段, 补丁解密失败

int CODE_LOAD_RELAUNCH = 12;//预加载阶段, 需要重启

int CODE_REQ_APPIDERR = 15;//查询阶段, appid异常

int CODE_REQ_SIGNERR = 16;//查询阶段, 签名异常

int CODE_REQ_UNAVAIABLE = 17;//查询阶段, 系统无效

int CODE_REQ_SYSTEMERR = 22;//查询阶段, 系统异常

int CODE_REQ_CLEARPATCH = 18;//查询阶段, 一键清除补丁

int CODE_PATCH_INVAILD = 20;//加载阶段, 补丁格式非法

//查询阶段的code说明

int CODE_QUERY_UNDEFINED = 31;//未定义异常

int CODE_QUERY_CONNECT = 32;//连接异常

int CODE_QUERY_STREAM = 33;//流异常

int CODE_QUERY_EMPTY = 34;//请求空异常

int CODE_QUERY_BROKEN = 35;//请求完整性校验失败异常

int CODE_QUERY_PARSE = 36;//请求解析异常

int CODE_QUERY_LACK = 37;//请求缺少必要参数异常

//预加载阶段的code说明

int CODE_PRELOAD_SUCCESS = 100;//预加载成功

int CODE_PRELOAD_UNDEFINED = 101;//未定义异常

int CODE_PRELOAD_HANDLE_DEX = 102;//dex加载异常

int CODE_PRELOAD_NOT_ZIP_FORMAT = 103;//基线dex非zip格式异常

int CODE_PRELOAD_REMOVE_BASEDEX = 105;//基线dex处理异常

//加载阶段的code说明 分三部分dex加载, resource加载, lib加载

//dex加载

int CODE_LOAD_UNDEFINED = 71;//未定义异常

int CODE_LOAD_AES_DECRYPT = 72;//aes对称解密异常

int CODE_LOAD_MFITEM = 73;//补丁SOPHIX.MF文件解析异常

int CODE_LOAD_COPY_FILE = 74;//补丁拷贝异常

int CODE_LOAD_SIGNATURE = 75;//补丁签名校验异常

int CODE_LOAD_SOPHIX_VERSION = 76;//补丁和补丁工具版本不一致异常

int CODE_LOAD_NOT_ZIP_FORMAT = 77;//补丁zip解析异常

int CODE_LOAD_DELETE_OPT = 80;//删除无效odex文件异常

int CODE_LOAD_HANDLE_DEX = 81;//加载dex异常

// 反射调用异常

int CODE_LOAD_FIND_CLASS = 82;

int CODE_LOAD_FIND_CONSTRUCTOR = 83;

int CODE_LOAD_FIND_METHOD = 84;

int CODE_LOAD_FIND_FIELD = 85;

int CODE_LOAD_ILLEGAL_ACCESS = 86;

//resource加载

public static final int CODE_LOAD_RES_ADDASSERTPATH = 123;//新增资源补丁包异常

//lib加载

int CODE_LOAD_LIB_UNDEFINED = 131;//未定义异常

int CODE_LOAD_LIB_CPUABIS = 132;//获取primaryCpuAbis异常

int CODE_LOAD_LIB_JSON = 133;//json格式异常

int CODE_LOAD_LIB_LOST = 134;//lib库不完整异常

int CODE_LOAD_LIB_UNZIP = 135;//解压异常

int CODE_LOAD_LIB_INJECT = 136;//注入异常

图片 31一般情况下依赖图片 32utdid重复,关闭传递性依赖图片 33maven地址

1.5 客户端本地SDK及DEMO下载

下载客户端SDK并集成(下载地址),Demo程序(Github)

当然,其中的接入复杂度这一条可以无视了,因为每一家的热修复都觉得自己的热修复接入方式比较傻瓜式。(理由大家都懂,hiahia...)其它几条还是具有一定的参考价值的。在之前项目热修复集成过AndFix、HotFix1.0,这次的HotFix2.0的发版给了我们一些全新的体验——图形界面一键打包、加密传输、签名校验和服务端控制发布与灰度功能还是相当强大。

1.7 补丁使用

生成的补丁需要上传到控制台。控制台地址

详情说明见:管理控制台使用

在阿里云平台创建App

图片 34

image

创建完成后对应的 AndroidManifest的配置

android:name="com.taobao.android.hotfix.IDSECRET"

android:value="App ID" />

android:name="com.taobao.android.hotfix.APPSECRET"

android:value="App Secret" />

android:name="com.taobao.android.hotfix.RSASECRET"

android:value="RSA密钥" />

图片 35

image.png

图片 36初始化

没补丁之前是这样的

图片 37

image.png

图片 38

image.png

图片 39差异包生成工具

1.3.2 接口说明

图片 40阿里系热修复对比

MyAppliction:
private void initHotfix() {
    String appVersion;
    try {
        appVersion = this.getPackageManager().getPackageInfo(this.getPackageName(), 0).versionName;
    } catch (Exception e) {
        appVersion = "1.0.0";
    }
    SophixManager.getInstance().setContext(this)
            .setAppVersion(appVersion)
            .setAesKey(null)
            .setEnableDebug(true)
            .setPatchLoadStatusStub(new PatchLoadStatusListener() {
                @Override
                public void onLoad(int mode, int code, String info, int handlePatchVersion) {
                    //补丁加载回掉通知
                    if (code == PatchStatus.CODE_LOAD_SUCCESS){
                        //表明补丁加载成功
                        Log.i("提示","表示补丁加载成功");
                    }else if(code == PatchStatus.CODE_LOAD_RELAUNCH){
                        //表明新补丁生效需要重启,开发者可以提示用户或者强制重启
                        // 建议: 用户可以监听进入后台事件, 然后调用killProcessSafely自杀,以此加快应用补丁,详见1.3.2.3
                    }else if(code == PatchStatus.CODE_LOAD_FAIL){
                        //清空本地所有补丁包
                        SophixManager.getInstance().cleanPatches();
                    }else{
                        //其他错误信息,查看PatchStatus类说明
                    }
                }
            }).initialize();
    // queryAndLoadNewPatch不可放在attachBaseContext 中,否则无网络权限,建议放在后面任意时刻,如onCreate中
    SophixManager.getInstance().queryAndLoadNewPatch();
}

Demo写的比较简单,主要就是为了快速测试一下
如果没有热更新,可能就要搞个临时版本或者甚至发布一个新版本,但是现在我们有了 Sophix ,就不需要这么麻烦了。

1.android4.X版本热修复后出现各种Crash和ANR的问题。根据提示联系了HotFix官方钉钉群的技术人员也未能解决该问题,他们提供的解决方案亲测无效。如果想尝试使用Sophix热修复可以参考一下这个解决方法。并且目前最新版本的Sophix3.0.2也同样存在该问题。当然,android5.0以上稳定性还是可以得。

1.2.3 权限说明

Sophix SDK使用到以下权限

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

热修复技术越来越成为一些公司的必备技术点(主要还是主管大大的要求 T.T)。它的优势显而易见,面对突发性BUG时候,相较于传统方式依靠于发新版apk上传到应用市场,无论是对于用户还是开发者而言 都是一次非常糟糕的体验。于是热修复技术应运而生,完美解决突发BUG而不被用户所察觉。下面我们来看下阿里最新的热修复技术Hotfix2.0 Sophix的集成使用和项目体验。

1.2.5 混淆配置

#基线包使用,生成mapping.txt

-printmappingmapping.txt

#生成的mapping.txt在app/buidl/outputs/mapping/release路径下,移动到/app路径下

#修复后的项目使用,保证混淆结果一致

-applymappingmapping.txt

#hotfix

-keep classcom.taobao.sophix.*{;}

-keep classcom.ta.utdid2.device.*{;}

#防止inline

-dontoptimize

在启动页或者其它非application位置完成查询补丁包的工作。

2.在部分5.x机型(例如Oppo 5.1)修复成功后会出现Dialog变形的问题。尚未找到官方给出的合理解释。

图片 41查询加载补丁包

图片 42热修复对比

本文由新葡京8455发布,转载请注明来源

关键词: