版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Dota_wy/article/details/82685356
Sophix 公有云接入
去年的时候写的一篇阿里云热修复的文章,那时它还是在公测阶段,一直没能投产,而今,公司项目需要集成已经投产的阿里Sophix功能,所以再次集成了一遍,记录下了步骤和遇到的一些问题。
一、在app/build.gradle中添加依赖包
dependencies {
implementation 'com.aliyun.ams:alicloud-android-hotfix:3.2.4'
implementation 'com.android.support:multidex:1.0.3'
}
附上我的Demo中的app下的build文件
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
defaultConfig {
applicationId "com.dotawang.sophixdemo"
minSdkVersion 14
targetSdkVersion 26
versionCode 1
versionName "1.0.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
ndk {
abiFilters 'armeabi', 'x86'
}
}
sourceSets {
main {
jniLibs.srcDirs = ['jniLibs']
}
}
//处理混淆上的问题
packagingOptions {
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/NOTICE'
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/ASL2.0'
exclude 'META-INF/notice.txt'
}
signingConfigs {
releaseConfig {
storeFile file("release.keystore")
storePassword "hschyf"
keyAlias "hswinner"
keyPassword "hschyf"
}
debugConfig {
storeFile file("release.keystore")
storePassword "hschyf"
keyAlias "hswinner"
keyPassword "hschyf"
}
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.releaseConfig
}
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.debugConfig
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
//noinspection GradleCompatible
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support:design:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'com.aliyun.ams:alicloud-android-hotfix:3.2.4'
implementation 'com.android.support:multidex:1.0.3'
//出现Error:Execution failed for task ':app:preDebugAndroidTestBuild'的解决方法
androidTestCompile('com.android.support:support-annotations:26.1.0') {
force = true
}
}
二、在项目下的build.gradle中添加依赖包
repositories {
... ...
maven {
url "http://maven.aliyun.com/nexus/content/repositories/releases"
}
}
附上我的Demo中的项目下的build文件
buildscript {
repositories {
google()
jcenter()
maven {
url "http://maven.aliyun.com/nexus/content/repositories/releases"
}
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
}
}
allprojects {
repositories {
google()
jcenter()
maven {
url "http://maven.aliyun.com/nexus/content/repositories/releases"
}
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
三、界面代码
1) MainActivity的代码(布局中就一个TextView控件,自行创建)
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends Activity {
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.tv);
initData();
}
private void initData() {
textView.setText("这是修复前的效果!!!");
//textView.setText("这是修复后的效果!!!");
//textView.setText("这是第二次修复后的效果!!!");
}
}
2) WinnerApplication的代码
import android.app.Application;
import com.taobao.sophix.SophixManager;
public class WinnerApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
//获取阿里热修复的补丁包 获取控制台状态
SophixManager.getInstance().queryAndLoadNewPatch();
}
}
3) SophixStubApplication的代码(阿里云热修复集成时要求加入的类,并且注意要在AndroidManifest中加入name去引入)
import android.content.Context;
import android.support.annotation.Keep;
import android.support.multidex.MultiDex;
import android.util.Log;
import com.taobao.sophix.PatchStatus;
import com.taobao.sophix.SophixApplication;
import com.taobao.sophix.SophixEntry;
import com.taobao.sophix.SophixManager;
import com.taobao.sophix.listener.PatchLoadStatusListener;
/**
*阿里公有云的稳健接入集成
*/
public class SophixStubApplication extends SophixApplication {
private final String TAG = "SophixStubApplication";
// 此处SophixEntry应指定真正的Application,并且保证RealApplicationStub类名不被混淆。
@Keep
@SophixEntry(WinnerApplication.class)
static class RealApplicationStub {}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
// 如果需要使用MultiDex,需要在此处调用,并去除原Applicaton中的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)
.setAesKey(null)
.setAppVersion(appVersion)
//设置null默认取AndroidManifest中设置的值
.setSecretMetaData(null, null, null)
//调试状态下true,上线模式下false
.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, "表明补丁加载成功");
} else if (code == PatchStatus.CODE_LOAD_RELAUNCH) {
// 如果需要在后台重启,建议此处用SharePreference保存状态。
Log.i(TAG, "用户可以监听进入后台事件, 然后应用自杀");
}else if (code == PatchStatus.CODE_REQ_CLEARPATCH){
//一键清除补丁状态 回退版本
} else {
// 其它错误信息, 查看PatchStatus类说明
Log.i(TAG," 其它错误信息, 查看PatchStatus类说明");
}
}
}).initialize();
}
// 在WinnerApplicationn中调用了这里就不需要了
// @Override
// public void onCreate() {
// super.onCreate();
// // queryAndLoadNewPatch不可放在attachBaseContext 中,否则无网络权限
// SophixManager.getInstance().queryAndLoadNewPatch();//再原有的Application中加入获取补丁包的方法onCreate()
//
// }
}
四、 AndroidManifest中引入代码:
android:name=".SophixStubApplication"
附上AndroidManifest的代码:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.dotawang.sophixdemo">
<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"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<application
android:name=".SophixStubApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true">
<meta-data
android:name="com.taobao.android.hotfix.IDSECRET"
android:value="25060525" />
<meta-data
android:name="com.taobao.android.hotfix.APPSECRET"
android:value="94e9460d950eef1b3d39f179bee007f0" />
<meta-data
android:name="com.taobao.android.hotfix.RSASECRET"
android:value="MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQD6xfkkCKr2zCI7C3HeAecXVtSzh91QIx+wt5f0h46vTPCAlQglvQwhLOXMTrNV3iCx4VLQcp8YDgfNh85ftuZa2X89z2nVjpZzoXOZzxaIXANBmsVgt68v/tQ8uN2nUFK2uZmsPDsYmpjBjzo9XYhbWBr0b+tylmsj3T5c5avTiVUD55FLq/SiLTvfVtqxDvAIpCjZj6azg6ncs6nZ3LmotCt1jhmXZHL94qmZyRVo1nAhrurUSxKgqkQnsowjWyxOpOa0r22umWi7st9aA+PG3h2G1STN7IFoxUAAdNZM+WhAtT98uZA8s1BH8RuBQZbXPVQ/KPAC5shWrXgetIg7AgMBAAECggEAfcR0IuJF++h88mfW/6SspUPjAPcOw3YaGqK5DuY9ZSWNKK+Vmnepcan2xfRidJomg4+h3PDfYU0IFMgbdF1iQgX6jqFLTtNoGS3LsEPv5QtghrJ8cvksX0HKZ3m/kH30PbfvnjXG3ZwLKGgQqV4TWNxjCFxpFNrjeOUotaZp+nhThketIgGkOWiUVULmcKhPUEZIQh0P4SVQmO8KoVSKwMT1kuwSLQOyZ1jZsU+1dtj/5OJ8Fz/XKLljxPvqPaQidhAyY2VAVKm31w/z7zSIE+lmJ5aj1+mcL5hGbc1wXHS1KVkvNPJc0NsSL1Izt+roTDRlzeuhGYKz0jkuS4djYQKBgQD/2M2+NJPdGIsCrW0ZsK7deOvQAtoODcHj93z0LOvMKGyUHnH6wOLBbjwnUhJ+VdPddH4Zm4imRaH6WOO8FahkMvB1BIM1AsMFPa3kP+JDsHq+QT5Bqlg3kebkhliz3a7dLEKNKizeZo5thgihBzCAssQ2w0F96SPjvCHohZqszwKBgQD67GRp/dZGftkK4mll4HODbl81aZgzoEOs7Dn0A372Xrpg+dG2xaMgms9IWKaODPJh15LymzWlhT42sP68Kh/StwXJPJc9nCaL3OtBNQuqrTqTAzErvcDuw5x65WiSZAky5TrkzthzILLdwQhjd82abuWUuhv7BIPjKdGf0wFA1QKBgH11Sgawb6WmqFwKwQos+sK9zhz1mQn1MxPfw5VVBdfaJsxHVasZtNgXf0Xk2A69daQNwNw7ybmHQdOqjRopIKbp18H6EYEINqu2QDRCI2j//GCZS7cVmia91BRR0ON6nIn2bzgb616vub35UPftt5oUj2UvQElG7wN4uMP16BA/AoGBAPIuswQyAVxtFeMRgBTaO+OA5dfRoRtC9c6y+YRw01vLNixfMnAr9TSE9sem+KpmCJMy1BvgfjjRj6iN0G+gYLKp/6WpG3hVfEbF5TI8lpQXOk+mZxEGxm4s0p0zSmjwsIg1A1DP683Co6CwrP4EJaeGnYOc1WDDjN/1/uM5bx45AoGBAIAZf1IY0ODHkAjasdUTk1Kuggu2JWp+nrVcZewVEf0U1iOp4zl2+SmiUMkYIsu514nxoVTbjF4cNI6puFSIGFUCjqylIAx4vqDUNiTbHm5cs7JNYm3ktNrF8CumtK/XlQC2R19CY5pEJ8goeqaArgVTvwhscLM1CVSTZPnsuLZb" />
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
五、proguard-rules.pro混淆代码的导入
#基线包使用,生成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
#导入阿里热修复Utils时混淆出错添加
-dontwarn com.alibaba.sdk.android.utils.**
-keep class android.support.multidex.**{*;}
-keep class com.hundsun.winner.application.base.WinnerApplication {
public <init>();
}
-keep class com.hundsun.winner.application.base.SophixStubApplication$RealApplicationStub
六、.gitignore忽略代码的添加
.DS_Store
*.swp
# Gradle
/build
.gradle/
target/
# Intellij project files
*.iml
*.ipr
*.iws
.idea/
# sonar
.sonar/
# Android
local.properties
nohup.out
到这里基本就结束了,下面的就剩下完成你要的签名包了,这些你直接应用我项目里面的也行,自己换也可以
注意的地方就是导入依赖这里:
1、报错Error:Execution failed for task ‘:app:preDebugAndroidTestBuild’
解决方法就是加入代码:
androidTestCompile('com.android.support:support-annotations:26.1.0') {
force = true
}
2、报错can’t find superclass or interface com.ut.mini.IUTApplication或者can’t find superclass or interface com.alibaba.sdk.android.beacon.Beacon$OnUpdateListener这些类似的情况
解决方法是:
在混淆规则中添加-dontwarn com.alibaba.sdk.android.utils.**即可解决
3、如果出现签名打的包无法安装的问题,而不集成热修复时项目是可以安装的问题的话,那就只有一种可能(前提是用的同一种机型安装的apk),看下图:
记得将V1和V2都勾选上,否则就会出现上面的情况,具体原因不知道,反正个人感觉有点反人类。
4、报错Error:Error: Expected resource of type color [ResourceType]
出现原因是:个人开始以为是项目中某些东西写的不规范导致的,但是不集成阿里热修复时是可以正常运行的,后来集成过后就出这问题了,开始怀疑阿里的热修复对规则有要求,最终反编译才知道是自己添加的混淆规则中有东西写错了
解决方法:
看下图
这里的包名一定要是你项目中的对应的类的路径,否则按照阿里云热修复集成文档上的复制来会出问题的(吐槽下:文档这里都不标注下这里要改为自己的包名的,还命名的跟三方的某个名字似的,不知道的真的容易被坑到)