请前往文档SDK下载&版本更新记录里下载“Android SDK”、“Android Demo工程”、“Android打包工具”和“Android调试工具”。如有任何疑问请加入钉钉群咨询。
Demo工程目录说明
gradle远程仓库依赖, 打开项目找到app的build.gradle文件,添加如下配置:
添加maven仓库地址:
repositories { maven { url "http://repo.baichuan-android.taobao.com/content/groups/BaichuanRepositories" } }
注意: 1.4.0版本的仓库地址已经发生了变更, 请更新到上述百川最新的仓库地址
添加gradle坐标版本依赖:
dependencies { compile 'com.taobao.android:alisdk-hotfix:1.4.0' }
跟其它版本不一样的地方, 1.4.0版本会传递性依赖utdid这个sdk, 所以不需要重复依赖.但是另一方面其它阿里系SDK也可能依赖了utdid这个SDK, 如果编译期间报utdid重复, 所以此时进行如下处理即可, 关闭传递性依赖:
compile ('com.taobao.android:alisdk-hotfix:1.4.0') { transitive = false }
utdid实际上是为设备生成唯一deviceid的一个基础类库
如若仓库访问失败, 那么用本地依赖的方式进行依赖, 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') }
编译期间报utdid重复, 去掉compile files('libs/utdid4all-1.1.5.3_proguard.jar')
依赖即可
¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨
编译期间报utdid类重复异常, 那么步骤2中添加的utdid4all-1.1.5.3_proguard.jar
从项目libs目录移除即可
¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨
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"/>
READ_EXTERNAL_STORAGE/ACCESS_WIFI_STATE权限属于Dangerous Permissions,自行做好android6.0以上的运行时权限获取
¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨
在AndroidManifest.xml
中间的application
节点下添加如下配置:
<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" />
将上述value中的值分别改为通过百川平台HotFix服务申请得到的App Secret和RSA密钥。
如何得到应用的AppSecret
和RSASecret
? 请查询获取SDK配置信息
¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨
-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 *; }
¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨
不管是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文件
initialize的调用应该尽可能的早. 强烈推荐在Application.onCreate()
中进行SDk初始化以及查询服务器是否有可用补丁的操作.
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) { // TODO: 10/24/16 表明补丁加载成功 } else if (code == PatchStatusCode.CODE_ERROR_NEEDRESTART) { // TODO: 10/24/16 表明新补丁生效需要重启. 业务方可自行实现逻辑, 提示用户或者强制重启, 建议: 用户可以监听进入后台事件, 然后应用自杀 } else if (code == PatchStatusCode.CODE_ERROR_INNERENGINEFAIL) { // 内部引擎加载异常, 推荐此时清空本地补丁, 但是不清空本地版本号, 防止失败补丁重复加载 //HotFixManager.getInstance().cleanPatches(false); } else { // TODO: 10/25/16 其它错误信息, 查看PatchStatusCode类说明 } } }).initialize();
initialize()方法内部会强制调用queryNewHotPatch()方法, 所以此处不需要额外再调用queryNewHotPatch()方法
¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨
该方法主要做些必要的初始化工作以及如果本地有补丁的话会加载补丁, 所以需要尽可能的早, 推荐在Application的onCreate方法中调用, 由于initialize方法参数越来越多变的原来越臃肿, 所以1.4.0版本修改了调用方式, initialize()方法调用之前你需要先调用如下几个方法, 方法调用说明如下:
-y
参数一起使用, 具体使用参见«Part2 生成patch补丁»的说明, 两者的值需要保持一致, 补丁才能正确被解密进而加载. 可选该接口需要自行实现并传入initialize方法中, 补丁加载状态会回调给该接口, 参数说明如下:
这里列举几个常见的code码说明, 详情查看SDK中PatchStatusCode类说明
该方法主要用于查询服务器是否有新的可用补丁. 首先initialize()方法内部会强制调用queryNewHotPatch()方法, 所以initialize()方法调用之后不需要再调用这个方法, 但是你可以在其它你需要的地方调用. 同时SDK内部限制连续两次queryNewHotPatch()方法调用不能短于3s, 否则的话就会报code:19的错误码. 如果查询到可用的话, 首先下载补丁到本地, 然后
同时1.4.0版本服务后台上线了“一键清除”补丁的功能, 所以如果后台点击了“一键清除”那么这个方法将会返回code:18的状态码. 此时本地补丁将会被强制清除, 同时不清除本地补丁版本号
参数force表示是否强制清空本地补丁版本号, 比如当前本地补丁版本号是10, 那么下次再次调用queryNewHotPatch方法时, 如果该参数为false: 不清除本地补丁版本号那么后台最新的补丁1就不会重新下载, 当然如果存在比10大的补丁版本仍然是可以下载下来的. 如果该参数为true: 清除本地补丁版本号, 本地补丁版本号将会被设置为0, 所以后台只要有任何发布的补丁都能够下载下来.
说明一:patch是针对客户端具体某个版本的,patch和具体版本绑定
说明二:针对某个具体版本发布的新补丁, 必须包含所有的bugfix, 而不能依赖补丁递增修复的方式, 因为应用仅可能加载一个补丁