阿里热修复之Sophix——公有云发布版集成步骤

版权声明:本文为博主原创文章,未经博主允许不得转载。 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]
出现原因是:个人开始以为是项目中某些东西写的不规范导致的,但是不集成阿里热修复时是可以正常运行的,后来集成过后就出这问题了,开始怀疑阿里的热修复对规则有要求,最终反编译才知道是自己添加的混淆规则中有东西写错了
解决方法:
看下图
这里写图片描述
这里的包名一定要是你项目中的对应的类的路径,否则按照阿里云热修复集成文档上的复制来会出问题的(吐槽下:文档这里都不标注下这里要改为自己的包名的,还命名的跟三方的某个名字似的,不知道的真的容易被坑到)

我的demo的github地址,有需要的可以自取:https://github.com/gitwangyang/SophixDemo.git

有问题欢迎咨询:QQ824553938

猜你喜欢

转载自blog.csdn.net/Dota_wy/article/details/82685356