闲的慌,作为一个一年多开发经验的小开发,不了解一下热修复怎么行,就算不会实现,也得会用吧,今天就尝试一下阿里爸爸的热修复(Sophix)
首先,我们需要注册一个阿里账号。这个大家应该都有,淘宝号就行
阿里官方地址奉上(https://www.aliyun.com/)
登录后,进入到 “产品----企业应用----移动热修复” 开通热修复功能
其次进入 “产品----企业应用----移动研发平台EMAS”
进入后,点击加号新建一个产品应用
填入产品名称,图标有则上传,无则可不填,直接确认即可。
新建产品成功后点击图标进入产品详情
一如既往,继续点击加号
填入你的App应用信息,并创建应用。
下载所生成的配置文件,并将其放置工程根路径下,打开可查看我们的appKey、appSecret、rsa秘钥等详细信息,后续操作需要用到该信息。
成功完成以上步骤后,此时我们就要进入我们的应用内部进行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"/>
然后在工程级build.gradle中加入classpath配置 classpath 'com.aliyun.ams:emas-services:1.0.1' 位置如下所示
buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:x.x.x'//此行请无视,使用你自己的版本好即可
classpath 'com.aliyun.ams:emas-services:1.0.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
然后在buildscript.repositories以及allprojects.repositories中加入maven仓库地址,位置如下所示
buildscript {
repositories {
google()//此行请无视,使用你自己的配置即可
jcenter()//此行请无视,使用你自己的配置即可
maven {
url "http://maven.aliyun.com/nexus/content/repositories/releases"
}
}
dependencies {
classpath 'com.android.tools.build:gradle:x.x.x'//此行请无视,使用你自己的版本好即可
classpath 'com.aliyun.ams:emas-services:1.0.1'//此行为上一步操作
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()//此行请无视,使用你自己的配置即可
jcenter()//此行请无视,使用你自己的配置即可
maven {
url "http://maven.aliyun.com/nexus/content/repositories/releases"
}
}
}
然后在app包级别,项目内中加入依赖
TODO :compile已准备过时,2018年底Android studio 会删除该语法,所以使用implementation或者api 来代替
dependencies {
....
implementation 'com.aliyun.ams:alicloud-android-hotfix:3.2.7'
}
可能有的伙伴应用会启用代码混淆,请在你的混淆文件清单加入以下配置
#基线包使用,生成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.**{*;}
-dontwarn com.alibaba.sdk.android.utils.**
#防止inline
-dontoptimize
最后加入Application配置类,代替我们原先的Application类,请细看下列代码以及注解,不要一味复制粘贴
package enjoyvideo.herden.com.hkws;
import com.taobao.sophix.SophixApplication;
import android.content.Context;
import android.support.annotation.Keep;
import android.util.Log;
import com.taobao.sophix.PatchStatus;
import com.taobao.sophix.SophixEntry;
import com.taobao.sophix.SophixManager;
import com.taobao.sophix.listener.PatchLoadStatusListener;
/**
* LikeBoke
* 2018/12/12
* Created by fhd
* Sophix入口类,专门用于初始化Sophix,不应包含任何业务逻辑。
* 此类必须继承自SophixApplication,onCreate方法不需要实现。
* 此类不应与项目中的其他类有任何互相调用的逻辑,必须完全做到隔离。
* AndroidManifest中设置application为此类,而SophixEntry中设为原先Application类。
* 注意原先Application里不需要再重复初始化Sophix,并且需要避免混淆原先Application类。
* 下方appKey、rsa等信息可在之前生成的Json配置文件中获取。
* 如有其它自定义改造,请咨询官方后妥善处理。
*/
public class SophixStubApplication extends SophixApplication {
private final String TAG = "SophixStubApplication";
// 此处SophixEntry应指定真正的Application,并且保证RealApplicationStub类名不被混淆。
@Keep
@SophixEntry(App.class)
static class RealApplicationStub {
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
// 如果需要使用MultiDex,需要在此处调用。
// MultiDex.install(this);
initSophix();
}
private void initSophix() {
String appVersion = "0.0.0";
try {
appVersion = this.getPackageManager()
.getPackageInfo(this.getPackageName(), 0)
.versionName;
} catch (Exception e) {
}
final SophixManager instance = SophixManager.getInstance();
instance.setContext(this)
.setAppVersion(appVersion)
.setSecretMetaData("填入appKey", "填入appSecret","填入rsaSecret")
.setEnableDebug(true)
.setEnableFullLog()
.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.i(TAG, "sophix load patch success!");
} else if (code == PatchStatus.CODE_LOAD_RELAUNCH) {
// 如果需要在后台重启,建议此处用SharePreference保存状态。
Log.i(TAG, "sophix preload patch success. restart app to make effect.");
}
}
}).initialize();
}
}
此处奉上官方稳健接入地址可对比查看(https://help.aliyun.com/document_detail/61082.html?spm=a2c4g.11174283.3.6.14e030c3Fjk7LA)
至此,我们的SDK已经接入成功。
下一步我们尝试修复一行代码。
我这里新建一个页面,只有一个TextView
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</LinearLayout>
页面效果如下
就是一个我们熟悉的Hello World!
然后假设这就是我们的第一版本App。我们先打包app,创建打包签名,打包出第一版本App后保存到本地
保存第一版本后,我们将TextView的text属性由Hello World!修改为你好。再次打包。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="你好!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</LinearLayout>
此时我们有了两个Apk包,一个我们称之为原始版本,一个我们称之为补正版本1
下一步,我们进入阿里热修复页面,依次执行下列步骤 “管理控制台---移动热修复--补丁管理--添加版本”
我们添加的版本号应与我们应用版本号一致,即与我们app级中build.gradle.versionName一致,如下所示的versionName
所以我们在弹出的窗口中填入1.0
添加版本后,进行上传补丁操作。补丁如何来呢?此处奉上补丁工具地址(https://help.aliyun.com/document_detail/93826.html?spm=a2c4g.11186623.2.10.28fc5b84ErRfJw)
此时此刻,本人只用过Mac版本的工具,所以windows以及Linux版本的补丁工具具体如何使用,并没有去了解,应该也是大同小异吧。
TODO:经过试验,Mac补丁工具下载后需要手动加入到应用程序中,才可正常使用。
使用补丁工具得到补丁后,上传至当前版本后,点击发布
重启后的效果图。
发布后,用户重新启动App时会自动下载替换补丁包。至此,我们的热修复大功告成。