前提条件
使用限制
当前快速接入方式,在Android 9.0及以上系统会有发生崩溃的风险,请选择SDK稳健接入方式接入。
如当前已采用“快速接入”方式接入,发布补丁时,请在控制台设置过滤机型,过滤Android 9.0及以上系统版本。
支持Android 4.3及以上系统,如自研设备和系统,请关闭系统级jit后进行接入。
如需要混淆,需要使用ProGuard进行混淆。
热修复SDK仅支持Java代码、资源文件和so文件的修复。
集成步骤
添加工程依赖
Android Studio集成方式
gradle远程仓库依赖, 打开项目找到App的build.gradle文件,添加如下配置:
添加Maven仓库地址:
repositories { maven { url "http://maven.aliyun.com/nexus/content/repositories/releases" } }
添加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.4.1' ...... }
如若仓库访问失败, 那么用本地依赖的方式进行依赖。
重要使用android studio打包生成apk时,要关闭instant run。
使用gradle plugin版本高于4.2时,可能会因为自动开启资源优化导致资源名称被混淆,进而导致在生成补丁时一直卡在“开始构建补丁...”,无法正常解析apk包。解决方案:在gradle.properties 中新增android.enableResourceOptimizations=false,重新生成基线包和修复包,然后再生成补丁。
如果开启了代码混淆,需要关闭R8,不然会导致生成的补丁较大。解决方案:在gradle.properties 中新增android.enableR8=false,重新生成基线包和修复包,然后再生成补丁。
若SDK集成过程中出现UTDID冲突,请参考阿里云-云产品SDK UTDID冲突解决方案。
eclipse集成方式
下载OneSDk.zip,解压出hotfix_core-release.aar文件后再解压这个aar文件。
复制解压文件jni目录下的libsophix.so到自己的jni目录下, eclipse jni目录一般指的就是项目libs目录。
复制utdid4all-x.x.x_proguard.jar和alicloud-android-utils-x.x.x.jar文件到项目libs目录下。
重命名classes.jar为sophix.jar并复制到项目libs目录下。
合并AndroidManifest.xml文件中的内容到本项目AndroidManifest.xml文件。
重要编译期间报utdid类重复异常, 那么步骤2中添加的
utdid4all-x.x.x_proguard.jar
从项目libs目录移除即可。
添加应用权限
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"/>
READ_EXTERNAL_STORAGE
权限属于Dangerous Permissions,仅调试工具获取外部补丁需要,不影响线上发布的补丁加载,调试时请自行做好android6.0以上的运行时权限获取。配置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密钥" />
将上述value中的值分别改为通过平台HotFix服务申请得到的App Secret和RSA密钥,出于安全考虑,建议使用setSecretMetaData这个方法进行设置,详见SDK API的方法说明。如找不到对应参数,可参考EMAS速入门中的“下载SDK”获取应用配置信息。
说明另外,热修复暂不支持EMAS统一插件的JSON文件读取。
App ID/App Secret
将被用于计量计费,请妥善保管注意安全。
混淆配置
#基线包使用,生成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文件以保证混淆结果一致。
使用proguad混淆
如果开启了代码混淆,需要关闭R8,使用proguard进行混淆。不然可能导致生成补丁异常。根据使用的Android Gradle Plugin版本,具体操作如下:
Android Gradle Plugin低于7.0
在项目根目录的gradle.properties中添加如下配置。
android.enableR8=false
Android Gradle Plugin 7.0以上
在项目根目录的build.gradle中添加如下ProGuard Gradle Plugin配置。
buildscript { repositories { // For the Android Gradle plugin. google() // For the ProGuard Gradle Plugin. mavenCentral() } dependencies { // The Android Gradle plugin. classpath("com.android.tools.build:gradle:x.y.z") // The ProGuard Gradle plugin. classpath("com.guardsquare:proguard-gradle:7.1.+") } }
在app目录的build.gradle中应用ProGuard Gradle Plugin。
apply plugin: 'com.guardsquare.proguard'
然后,关闭R8混淆。
android { buildTypes { release { // 关闭 R8. minifyEnabled false } } }
最后,配置ProGuard混淆。
android { ... } proguard { configurations { release { defaultConfiguration 'proguard-android.txt' configuration 'proguard-rules.pro' } debug { defaultConfiguration 'proguard-android-debug.txt' configuration 'proguard-rules.pro' } } }
初始化
initialize的调用应该尽可能的早,必须在
Application.attachBaseContext()
的最开始(在super.attachBaseContext之后,如果有Multidex,也需要在Multidex.install之后)进行SDK初始化操作,初始化之前不能用到其他自定义类,否则极有可能导致崩溃。而查询服务器是否有可用补丁的操作可以在后面的任意地方。不建议在Application.onCreate()
中初始化,因为如果带有ContentProvider,就会使得Sophix初始化时机太迟从而引发问题。以下为快速接入的初始化方式,直接在已有Application中添加以下代码即可。我们更推荐使用SDK稳健接入,采用稳健接入后修复范围更广,稳定性更高。
// initialize必须放在attachBaseContext最前面,初始化代码直接写在Application类里面,切勿封装到其他类。 SophixManager.getInstance().setContext(this) .setAppVersion(appVersion) .setAesKey(null) .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) { // 表明补丁加载成功 } else if (code == PatchStatus.CODE_LOAD_RELAUNCH) { // 表明新补丁生效需要重启. 开发者可提示用户或者强制重启; // 建议: 用户可以监听进入后台事件, 然后调用killProcessSafely结束进程,以此加快应用补丁。 } else { // 其它错误信息, 查看PatchStatus类说明 } } }).initialize(); // queryAndLoadNewPatch不可放在attachBaseContext 中,否则无网络权限,建议放在后面任意时刻,如onCreate中 SophixManager.getInstance().queryAndLoadNewPatch();