阿里热修复之Sophix——专有云发布版集成步骤
阿里热修复之Sophix——专有云
应公司业务需求,和阿里云的阿里热修复相关技术人员合作,整了波专有云的热修复集成Demo
一、app/build.gradle下的代码
注意:第二行的代码在集成中要开启的,这里注释掉是为让app可以本地run起来看到界面
apply plugin: 'com.android.application'
//调试无法安装时注释掉这行
//apply plugin: 'com.taobao.sophix.emas'configurations {providedCompileall*.exclude group: 'com.taobao.android', module: 'tnet-jni'all*.exclude group: 'com.taobao.android', module: 'tlog_adapter'all*.exclude group: 'com.aliyun.ams', module:'alicloud-android-utdid'all*.exclude group: 'com.aliyun.ams', module: 'alicloud-android-ut'
}
configurations.all {resolutionStrategy {cacheChangingModulesFor(0, 'SECONDS')cacheChangingModulesFor(0, 'SECONDS')}
}
//task wrapper(type: Wrapper) {
// gradleVersion = '4.1'
// distributionUrl = 'http://emas-deploy.oss-cn-hangzhou.aliyuncs.com/gradle-4.1-all.zip'
//}
//tasks.whenTaskAdded { task ->
// if (task.name.contains("DebugAndroidTest")) {
// task.setEnabled(false);
// }
//}android {compileSdkVersion 26defaultConfig {applicationId "com.dotawang.sophixemasdemo"minSdkVersion 15targetSdkVersion 26versionCode 1versionName "1.0.0"testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"ndk {abiFilters 'armeabi', 'x86', 'armeabi-v7a', 'arm64-v8a'}//语言类型resConfigs "en", "fr"}dexOptions{javaMaxHeapSize = '2048m'additionalParameters=["--no-strict"]}sourceSets {main {jniLibs.srcDirs = ['jniLibs']}}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 trueproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'signingConfig signingConfigs.releaseConfig}debug {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
// signingConfig signingConfigs.debugConfig}}
}dependencies {implementation fileTree(dir: 'libs', include: ['*.jar'])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'compile 'com.android.support:appcompat-v7:26.1.0'compile 'com.android.support:design:26.1.0'compile 'com.squareup.picasso:picasso:2.5.2'//出现Error:Execution failed for task ':app:preDebugAndroidTestBuild'的解决方法androidTestCompile('com.android.support:support-annotations:26.1.0') {force = true}compile 'com.aliyun.ams:alicloud-android-hotfix:3.2.4'compile('com.emas.lib:emas-core:1.0.11-SNAPSHOT@aar') { transitive true }/************基础库 START**********/compile('com.alibaba:fastjson:1.1.54.android@jar') { transitive true }compile('com.taobao.android:mtopsdk_allinone:3.0.6.4-open@jar') { transitive true }compile('com.taobao.android:networksdk:3.3.5-open@jar') { transitive true }compile('com.taobao.android:tnet4android:3.1.14.6@aar') { transitive true }compile('com.taobao.android:utdid4all:1.1.5.3_proguard@jar') { transitive true }/************基础库 END**********//************高可用 SDK START**********/compile('com.taobao.android:accs_sdk_taobao:3.3.3.1-open') { transitive true }compile('com.taobao.android:ut-analytics:1.1.0.1-open@aar') { transitive true }compile('com.alibaba.ha:alihatbadapter:1.1.0.3-open@aar') {transitive true//exclude group:'com.taobao.android', module:'tlog_uploader_oss'}//compile ('com.taobao.android:tlog_uploader_ceph:1.1.0.3-open@aar')//默认oss通道需要依赖oss的三方库compile ('com.squareup.okhttp3:okhttp:3.4.1@jar')compile ('com.squareup.okio:okio:1.9.0@jar')compile ('com.aliyun.dpa:oss-android-sdk:2.4.2@aar')/************高可用 SDK END**********/
}//Sophix
apply from: 'common.gradle'
group = "com.dotawang.sophixemasdemo"//包名
version = android.defaultConfig.versionName + '-SNAPSHOT'
apply plugin: 'maven'
apply plugin: 'maven-publish'publishing {publications {maven(MavenPublication) {if (project.gradle.startParameter.toString().contains("Debug")) {artifact "${project.buildDir}/sophix/${project.name}-debug.sar"artifactId "sar-debug"} else {artifact "${project.buildDir}/sophix/${project.name}-release.sar"artifactId "sar-release"}}}repositories {if (version.endsWith("-SNAPSHOT")) {maven {url "http://nexus.emas-ha.cn:8081/repository/maven-snapshots/"credentials {username = CUSTOM_REPOSITORY_USERNAMEpassword = CUSTOM_REPOSITORY_PASSWORD}}} else {maven {url "http://nexus.emas-ha.cn:8081/repository/maven-releases/"credentials {username = CUSTOM_REPOSITORY_USERNAMEpassword = CUSTOM_REPOSITORY_PASSWORD}}}}
}
二、在项目的app文件夹下创建个common.gradle的文件,位置如下图:
common.gradle的代码如下:
def emas_version_name = getEnvValue('EMAS_VERSION_NAME')
def emas_version_code = getEnvValue('EMAS_VERSION_CODE')
def emas_base_version = getEnvValue('EMAS_BASE_VERSION')if (emas_version_code) {android.defaultConfig.versionCode = emas_version_code.toInteger()println("emas_version_code=" + emas_version_code)
}if (emas_base_version) {println("emas_base_version=" + emas_base_version)
}if (emas_version_name) {android.defaultConfig.versionName = emas_version_nameprintln("emas_version_name=" + emas_version_name)
}String getEnvValue(key) {return getEnvValue(key, null)
}String getEnvValue(key, defValue) {def val = System.getProperty(key);if (null != val) {return val}val = System.getenv(key);if (null != val) {return val}return defValue
}
三、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
-keepclassmembers class com.dotawang.sophixemasdemo.WinnerApplication {
public ();
}
-keep class com.dotawang.sophixemasdemo.SophixStubApplication$RealApplicationStub
-dontpreverify
-dontusemixedcaseclassnames
-optimizations code/removal/simple,code/removal/advanced,code/removal/variable,code/removal/exception,code/simplification/branch,code/simplification/field,code/simplification/cast,code/simplification/arithmetic,code/simplification/variable
-keepattributes Exceptions,InnerClasses,Signature,SourceFile,LineNumberTable,*Annotation*
-renamesourcefileattribute Taobao
-allowaccessmodification
-optimizationpasses 1
#防止inline
-dontoptimize
-target 1.6
#-verbose
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-dontwarn okio.**
-dontwarn com.squareup.okhttp.**
-dontwarn okhttp3.**
-dontwarn javax.annotation.**
-dontwarn com.android.volley.toolbox.**
-dontwarn com.facebook.infer.**
-dontwarn org.mozilla.javascript.**
-dontwarn org.mozilla.classfile.**
-dontwarn java.awt.**
-dontwarn com.taobao.**
-dontwarn com.google.android.maps.**
-dontwarn android.support.v7.widget.**
-dontwarn android.support.v4.**
-dontwarn com.tencent.mm.sdk.**
-dontwarn org.android.agoo.**
-dontwarn com.amap.api.**
-dontwarn com.autonavi.amap.**
-dontwarn com.ut.**
-dontwarn com.robotium.**
-dontwarn com.alibaba.fastjson.**
-dontwarn android.taobao.**
-dontwarn com.alibaba.mobileim.**
-dontwarn com.autonavi.**
-dontwarn com.amap.**
-dontwarn ***
#############公共的混淆keep选项, 可删除与工程中有重复部分 #############
-keep class * extends android.app.Application
-keep class * extends android.app.Activity
-keep class * extends android.app.Service
-keep class com.google.inject.Binder
-keepclassmembers class * {
@com.google.inject.Inject (...);
}
# There's no way to keep all @Observes methods, so use the On*Event convention to identify event handlers
-keepclassmembers class * {
void *(**On*Event);
}
-keep public class * extends android.view.View {
public (android.content.Context);public (android.content.Context, android.util.AttributeSet);public (android.content.Context, android.util.AttributeSet, int);public void set*(...);
}
-keep public class roboguice.**
-keep class rx.**{*;}
# 为了atlas注入
-keepclassmembers class ** {
private (...);public (...);(...);
}-keepclassmembernames class **.R$* {*;}
-keepclassmembernames class **.R {*;}
-keepclassmembers class **{
public static final ;
}
-keepclassmembers class * extends android.content.Context {
public void *(android.view.View);public void *(android.view.MenuItem);
}-keepclassmembers class * implements android.os.Parcelable {
static ** CREATOR;
}-keepclassmembers class * {
public static ** asInterface(***);
}-keepclassmembers class ** {
public void onEvent*(***);
}-keepclassmembers enum * {
public static **[] values();public static ** valueOf(...);**[] $VALUES;
}-keepclasseswithmembernames class * {
native ;
}# Keep native methods
-keepclassmembers class * {
native ;
}-keepclassmembers class * implements java.io.Serializable {
public ;public ;private static final java.io.ObjectStreamField[] serialPersistentFields;private void writeObject(java.io.ObjectOutputStream);private void readObject(java.io.ObjectInputStream);java.lang.Object writeReplace();java.lang.Object readResolve();
}-keep class * implements android.os.Parcelable {
public ;public ;public static final android.os.Parcelable$Creator *;
}
#############公共的混淆keep选项, 可删除与工程中有重复部分 #######################################基础库##########################
#fastjson
-keep class com.alibaba.fastjson.** {*;}
#tnet
#-keepclasseswithmembernames class org.android.spdy.** {
# native ;
#}
-keep public class org.android.spdy.**{*;}
#mtop
-keep class anetwork.network.cache.**{*;}
-keep class com.taobao.tao.remotebusiness.**{*;}
-keep class mtopsdk.**{*;}
#network
-keep class anet.channel.**{*;}
-keep class anetwork.channel.**{*;}
##########################基础库####################################################高可用##########################
#keep ha alihatbadapter
-keep class com.alibaba.ha.**{*;}
-keep class com.taobao.tlog.**{*;}
#keep ha utdid
-keep class com.ut.device.**{*;}
-keep class com.ta.utdid2.device.**{*;}
#keep ha ut
-keep public class com.alibaba.mtl.** { *;}
-keep public class com.ut.mini.** { *;}
#keep ha crashreporter
-keep class com.alibaba.motu.crashreporter.**{ *;}
-keep class com.uc.crashsdk.**{*;}
#keep ha telescope
-keep class com.ali.telescope.**{ *;}
-keep class libcore.io.**{*;}
-keep class android.app.**{*;}
-keep class dalvik.system.**{*;}
#keep ha tlog
-keep class com.taobao.tao.log.**{*;}
-keep class com.taobao.android.tlog.**{*;}
#keep tbrest
-keep class com.alibaba.motu.**{*;}
##########################高可用#####################################################远程配置##########################
-keep class com.taobao.orange.**{*;}
###########################远程配置#####################################################其他##########################
-keep class sun.misc.Unsafe { *; }
-keep class com.alibaba.** {*;}
#关闭日志
#-assumenosideeffects class android.util.Log {
# public static boolean isLoggable(java.lang.String, int);
# public static int v(...);
# public static int w(...);
# public static int d(...);
# public static int i(...);
#}
#-assumenosideeffects class java.lang.Throwable {
# public void printStackTrace();
#}-keep public class android.support.design.widget.BottomNavigationView { *; }
-keep public class android.support.design.internal.BottomNavigationMenuView { *; }
-keep public class android.support.design.internal.BottomNavigationPresenter { *; }
-keep public class android.support.design.internal.BottomNavigationItemView { *; }
###########################其他############################ 去除BottomNavigationView的tab大于三个的时候的切换效果
-keepclassmembers class android.support.design.internal.BottomNavigationMenuView {
boolean mShiftingMode;
}
四、项目下的build.gradle代码
// Top-level build file where you can add configuration options common to all sub-projects/modules.buildscript {repositories {mavenLocal()maven {url SDK_REPOSITORY_URLcredentials {username = SDK_REPOSITORY_USERNAMEpassword = SDK_REPOSITORY_PASSWORD}}maven { url "http://maven.aliyun.com/nexus/content/repositories/google/"}maven { url "http://maven.aliyun.com/nexus/content/repositories/releases/"}maven { url "http://maven.aliyun.com/nexus/content/groups/public/"}maven { url "http://nexus.emas-ha.cn:8081/repository/maven-releases/" }maven { url "http://nexus.emas-ha.cn:8081/repository/maven-snapshots/" }}dependencies {classpath 'com.android.tools.build:gradle:3.0.1'classpath 'com.taobao.android:sophix-emas-plugin:0.5.10-SNAPSHOT'//Sophix// NOTE: Do not place your application dependencies here; they belong// in the individual module build.gradle files}
}allprojects {repositories {mavenLocal()maven {url SDK_REPOSITORY_URLcredentials {//SDK中心仓库username = SDK_REPOSITORY_USERNAMEpassword = SDK_REPOSITORY_PASSWORD}}maven { url "http://maven.aliyun.com/nexus/content/repositories/google/"}maven { url "http://maven.aliyun.com/nexus/content/repositories/releases/"}maven { url "http://maven.aliyun.com/nexus/content/groups/public/"}maven { url "http://nexus.emas-ha.cn:8081/repository/maven-releases/" }maven { url "http://nexus.emas-ha.cn:8081/repository/maven-snapshots/" }}
}task clean(type: Delete) {delete rootProject.buildDir
}
五、gradle.properties的代码中加入下面代码
注意:这里代码主要是用来配置sdk仓库和产物仓库的2组账号密码
#SDK中心仓库
SDK_REPOSITORY_URL = http://nexus-ce.emas-poc.com/repository/maven-public/
SDK_REPOSITORY_USERNAME = developer
SDK_REPOSITORY_PASSWORD = fT&iXg$16jIh##yL#产物仓库
CUSTOM_REPOSITORY_HOST = nexus.emas-ha.cn:8081
CUSTOM_REPOSITORY_USERNAME = developer
CUSTOM_REPOSITORY_PASSWORD = RSs6KfAdXJOrA6rx
六、各大界面的代码
1)MainActivity的布局xml代码
<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:orientation="vertical"android:layout_height="match_parent"android:layout_gravity="center"tools:context="com.dotawang.sophixemasdemo.MainActivity"><ImageView
android:id="@+id/iv"android:src="@mipmap/ic_launcher"android:layout_gravity="center"android:layout_width="200dp"android:layout_height="200dp" /><TextView
android:id="@+id/tv1"android:layout_marginTop="10dp"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="补丁内容修改"android:layout_gravity="center"android:gravity="center"/><Button
android:id="@+id/bt_crash"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="崩溃"android:layout_gravity="center"android:gravity="center"/><Button
android:id="@+id/bt_ca"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="线程卡顿"android:layout_gravity="center"android:gravity="center"/><Button
android:id="@+id/bt_query"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="拉取补丁"android:layout_gravity="center"android:gravity="center" /><TextView
android:id="@+id/tv_code"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="20dp"/>
LinearLayout>
2)MainActivity的界面代码
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;import com.squareup.picasso.Picasso;
import com.taobao.sophix.SophixManager;/**
1、AndroidManifest不支持
2、build 基础依赖包升级不支持
3、导入sophix插件,无法直接打包*/
public class MainActivity extends Activity {private ImageView imageView;private TextView textView;private TextView tv_code;private Button bt_crash,bt_ca,bt_query;private Handler handler = new Handler();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initData();initListener();initThread();}private void initThread() {updata(SophixStubApplication.cacheMsg.toString());SophixStubApplication.msgDisplayListener = new SophixStubApplication.MsgDisplayListener() {@Overridepublic void handle(final String msg) {runOnUiThread(new Runnable() {@Overridepublic void run() {updata(msg);}});}};handler.postDelayed(new Runnable() {@Overridepublic void run() {// 请求补丁SophixManager.getInstance().queryAndLoadNewPatch();handler.postDelayed(this, 10 * 1000);}}, 1 * 1000);}private void updata(String cacheMsg) {if (cacheMsg != null){tv_code.setText(cacheMsg);}}private void initListener() {imageView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {//1、ic_launcher//2、https://i.loli.net/2018/09/12/5b9881e9ed5e8.jpg//3、test本地Picasso.with(MainActivity.this).load("https://i.loli.net/2018/09/12/5b9881e9ed5e8.jpg").into(imageView);}});textView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {textView.setText("修复1");//textView.setText("修复2");//textView.setText("修复3");}});bt_crash.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {throw new RuntimeException();}});bt_ca.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {try{Thread.sleep(20*1000);}catch (Exception e){e.printStackTrace();}}});bt_query.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {SophixManager.getInstance().queryAndLoadNewPatch();}});}private void initData() {imageView = findViewById(R.id.iv);textView = findViewById(R.id.tv1);tv_code = findViewById(R.id.tv_code);bt_crash = findViewById(R.id.bt_crash);bt_ca = findViewById(R.id.bt_ca);bt_query = findViewById(R.id.bt_query);}
}
3)SophixStubApplication的代码
import android.content.Context;
import android.support.annotation.Keep;
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;/*** Created on 2018/9/12* Title:* Description:** @author Android-汪洋* update 2018/9/12*/
public class SophixStubApplication extends SophixApplication {private final String TAG = "SophixStubApplication";// 此处SophixEntry应指定真正的Application,并且保证RealApplicationStub类名不被混淆。@Keep@SophixEntry(WinnerApplication.class)static class RealApplicationStub {}@Overrideprotected 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)//host 域名.setHost("hotfix-gate.emas-poc.com", false).setEnableDebug(true).setEnableFullLog().setPatchLoadStatusStub(new PatchLoadStatusListener() {@Overridepublic void onLoad(final int mode, final int code, final String info, final int handlePatchVersion) {String msg = new StringBuilder("").append("Mode:").append(mode).append(" Code:").append(code).append(" Info:").append(info).append(" HandlePatchVersion:").append(handlePatchVersion).toString();if (msgDisplayListener != null) {msgDisplayListener.handle(msg);} else {cacheMsg.append("\n").append(msg);}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();}public interface MsgDisplayListener {void handle(String msg);}public static MsgDisplayListener msgDisplayListener = null;public static StringBuilder cacheMsg = new StringBuilder();
}
4)WinnerApplication的代码
import android.app.Application;import com.taobao.sophix.SophixManager;/*** Created on 2018/9/12* Title:* Description:** @author Android-汪洋* update 2018/9/12*/
public class WinnerApplication extends Application {@Overridepublic void onCreate() {super.onCreate();EmasInit emas = EmasInit.getInstance().setmApplication(this);emas.initHA();SophixManager.getInstance().queryAndLoadNewPatch();}
}
5)EmasInit的代码
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.res.Resources;
import android.text.TextUtils;
import android.util.Log;import com.alibaba.ha.adapter.AliHaAdapter;
import com.alibaba.ha.adapter.AliHaConfig;
import com.alibaba.ha.adapter.Plugin;
import com.alibaba.ha.adapter.Sampling;
import com.taobao.accs.ACCSClient;
import com.taobao.accs.ACCSManager;
import com.taobao.accs.AccsClientConfig;
import com.taobao.accs.AccsException;
import com.taobao.accs.IAppReceiver;
import com.taobao.accs.common.Constants;
import com.taobao.accs.utl.ALog;import org.android.spdy.SpdyProtocol;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;import anet.channel.AwcnConfig;
import anet.channel.SessionCenter;
import anet.channel.strategy.ConnEvent;
import anet.channel.strategy.ConnProtocol;
import anet.channel.strategy.IConnStrategy;
import anet.channel.strategy.IStrategyInstance;
import anet.channel.strategy.IStrategyListener;
import anet.channel.strategy.StrategyCenter;
import anet.channel.strategy.dispatch.HttpDispatcher;
import anetwork.channel.config.NetworkConfigCenter;
import anetwork.channel.http.NetworkSdkSetting;
import mtopsdk.common.util.TBSdkLog;
import mtopsdk.mtop.global.SwitchConfig;
import mtopsdk.mtop.intf.Mtop;
import mtopsdk.mtop.intf.MtopEnablePropertyType;
import mtopsdk.mtop.intf.MtopSetting;
import mtopsdk.security.LocalInnerSignImpl;/*** Created by jason on 18/1/15.*/public class EmasInit {public static final int DEBUG = 1; //测试环境public static final int RELEASE = 2; //发布环境/*配置信息*/protected String mAppkey = "20000297";//"10000066";//"10000039";//"10000078";//"60039748";protected String mAppSecret = "53b92bd7eb29931ab25580506285c9b8";//"1426c10c5ce57d6cb29e016a816421a7";//"c7795717b2306055f21fb33418c1d011";//"2e00a7e9ab2048daabd4977170d37c4a";//"ab5ff148782b467bb0b310c4acd70abd"//"fe240d4b8f4b31283863cc9d707e2cb1"protected String mCacheURL = "http://cdn.emas-poc.com/eweex/";protected String mACCSDoman = "accs.emas-poc.com";protected Map mIPStrategy;protected String mMTOPDoman = "aserver.emas-poc.com";protected String mHAUniversalHost = "adash.emas-poc.com";protected String mHAOSSBucketName = "emas-ha-remote-log-poc";protected String mHARSAPublicKey;protected String mStartActivity = "com.taobao.demo.WelcomActivity";protected String mChannelID = "1001@DemoApp_Android_" + BuildConfig.VERSION_NAME;protected String PUSH_TAG = "POC";protected boolean mUseHttp = true;protected int mEnv = DEBUG;private Application mApplication;private static final String TAG = "EmasInit";public final static String SERVICE_ID = "4272_mock";//private static final String[] TEST_EMAS = new String[]{"acs.alibaba-inc.com", "11.163.130.35", "80"};private final static Map SERVICES = new HashMap() {private static final long serialVersionUID = 2527336442338823324L;{//自定义服务put(SERVICE_ID, "com.taobao.demo.accs.TestAccsService");}};/*** 切换成单例*/private static class CreateInstance {private static EmasInit instance = new EmasInit();}public static EmasInit getInstance() {return CreateInstance.instance;}private EmasInit() {//不能生成对象}//先设置mApplicationpublic EmasInit setmApplication(Application application) {this.mApplication = application;//初始化firstInit();return this;}private void firstInit() {Application application = mApplication;StringBuilder builder = new StringBuilder();try {int id = application.getResources().getIdentifier("ttid", "string", application.getPackageName());if (id > 0) {mChannelID = builder.append(application.getString(id)).append("@").append(application.getResources().getString(application.getApplicationInfo().labelRes)).append("_").append("Android").append("_").append(BuildConfig.VERSION_NAME).toString();}} catch (Resources.NotFoundException e) {Log.d(TAG, "no channel id in res" + e.toString());}}/********************UPDATE SDK START **************************/private void initMtop() {if (mEnv == DEBUG) {TBSdkLog.setTLogEnabled(false);TBSdkLog.setLogEnable(TBSdkLog.LogEnable.DebugEnable);}//关闭密文if (mUseHttp) {NetworkConfigCenter.setSSLEnabled(false);}//[option]关闭MTOP请求长链,调用后Mtop请求直接调用NetworkSDK的HttpNetwork发请求SwitchConfig.getInstance().setGlobalSpdySwitchOpen(false);//关闭MTOPSDK NewDeviceID逻辑MtopSetting.setEnableProperty(Mtop.Id.INNER, MtopEnablePropertyType.ENABLE_NEW_DEVICE_ID, false);//设置自定义全局访问域名MtopSetting.setMtopDomain(Mtop.Id.INNER, mMTOPDoman, mMTOPDoman, mMTOPDoman);//设置自定义签名使用的appKey和appSecretMtopSetting.setISignImpl(Mtop.Id.INNER, new LocalInnerSignImpl(mAppkey, mAppSecret));MtopSetting.setAppVersion(Mtop.Id.INNER, BuildConfig.VERSION_NAME);Mtop mtopInstance = Mtop.instance(Mtop.Id.INNER, mApplication.getApplicationContext(), mChannelID);}/********************UPDATE SDK END **************************//********************HA SDK START **************************/public void initHA() {//开启if (mEnv == DEBUG) {AliHaAdapter.getInstance().openDebug(true);}AliHaAdapter.getInstance().changeHost(mHAUniversalHost);AliHaAdapter.getInstance().tLogService.changeRemoteDebugHost(mHAUniversalHost);AliHaAdapter.getInstance().tLogService.changeRemoteDebugOssBucket(mHAOSSBucketName);if (!TextUtils.isEmpty(mHARSAPublicKey)) {AliHaAdapter.getInstance().tLogService.changeRasPublishKey(mHARSAPublicKey);}initHACrashreporterAndUt();AliHaAdapter.getInstance().openHttp(mUseHttp);initAccs();AliHaAdapter.getInstance().removePugin(Plugin.crashreporter); //tlog 依赖accsAliHaAdapter.getInstance().removePugin(Plugin.ut);AliHaAdapter.getInstance().telescopeService.setBootPath(new String[]{mStartActivity}, System.currentTimeMillis());AliHaAdapter.getInstance().start(buildAliHaConfig());}private AliHaConfig buildAliHaConfig() {//ha初始化AliHaConfig config = new AliHaConfig();config.isAliyunos = false;config.appKey = mAppkey;config.userNick = "you need set user name";config.channel = mChannelID;config.appVersion = BuildConfig.VERSION_NAME;config.application = mApplication;config.context = mApplication;return config;}private void initHACrashreporterAndUt() {AliHaAdapter.getInstance().startWithPlugin(buildAliHaConfig(), Plugin.crashreporter);AliHaAdapter.getInstance().startWithPlugin(buildAliHaConfig(), Plugin.ut);AliHaAdapter.getInstance().utAppMonitor.changeSampling(Sampling.All);}private void initAccs() {if (mIPStrategy != null && mIPStrategy.size() > 0) {initNetwork();}boolean isDebug = ((mApplication.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0);if (isDebug) { //debug版本, 打开日志开关, 方便排查问题ALog.setUseTlog(false);anet.channel.util.ALog.setUseTlog(false);}new Thread() { //建议异步进行初始化@Overridepublic void run() {int env = Constants.RELEASE;int pubkey = SpdyProtocol.PUBKEY_PSEQ_EMAS;//SpdyProtocol.PUBKEY_SEQ_TESTString appkey = mAppkey;//"4272"String appsecret = mAppSecret;//"257461a8005f538382640d4894dd193a04d18e1b4a7a5ee214b6d660778d3943"String emasHost = mACCSDoman;SharedPreferences sp = mApplication.getSharedPreferences("emas_accs", Context.MODE_PRIVATE);String key = sp.getString("appkey", null);String secret = sp.getString("appsecret", null);appkey = TextUtils.isEmpty(key) ? appkey : key;appsecret = TextUtils.isEmpty(secret) ? appsecret : secret;try {ACCSManager.setAppkey(mApplication.getApplicationContext(), mAppkey, env);//兼容老接口 如果有任意地方使用老接口,必须setAppkeyNetworkSdkSetting.init(mApplication.getApplicationContext());//关闭AMDC请求HttpDispatcher.getInstance().setEnable(false);ACCSClient.setEnvironment(mApplication.getApplicationContext(), env);AwcnConfig.setAccsSessionCreateForbiddenInBg(false);AccsClientConfig clientConfig = new AccsClientConfig.Builder().setAppKey(appkey).setAppSecret(appsecret).setInappHost(emasHost).setInappPubKey(pubkey).setTag(AccsClientConfig.DEFAULT_CONFIGTAG).setConfigEnv(env).build();ACCSClient.init(mApplication, clientConfig);ACCSClient.getAccsClient(AccsClientConfig.DEFAULT_CONFIGTAG).bindApp(mChannelID, mAppReceiver);} catch (AccsException e) {ALog.w(TAG, "initDefaultAccs", e);}}}.start();}private IAppReceiver mAppReceiver = new IAppReceiver() {private String TAG = "mAppReceiver";@Overridepublic void onBindApp(int errorCode) {ALog.i(TAG, "onBindApp", "errorCode", errorCode);try {ACCSClient.getAccsClient(AccsClientConfig.DEFAULT_CONFIGTAG).bindUser("123324234");} catch (AccsException e) {e.printStackTrace();}}@Overridepublic void onUnbindApp(int errorCode) {ALog.i(TAG, "onUnbindApp", "errorCode", errorCode);}@Overridepublic void onBindUser(String userId, int errorCode) {ALog.i(TAG, "onBindUser", "errorCode", errorCode);}@Overridepublic void onUnbindUser(int errorCode) {ALog.i(TAG, "onUnbindUser", "errorCode", errorCode);}@Overridepublic void onSendData(String dataId, int errorCode) {ALog.i(TAG, "onSendData");}@Overridepublic void onData(String userId, String dataId, byte[] data) {ALog.i(TAG, "onData");}@Overridepublic String getService(String serviceId) {String service = SERVICES.get(serviceId);return service;}@Overridepublic Map getAllServices() {return SERVICES;}};private void initNetwork() {SessionCenter.init(mApplication);final IStrategyInstance instance = StrategyCenter.getInstance();StrategyCenter.setInstance(new IStrategyInstance() {@Overridepublic void initialize(Context context) {instance.initialize(context);}@Overridepublic void switchEnv() {instance.switchEnv();}@Overridepublic void saveData() {instance.saveData();}@Overridepublic String getFormalizeUrl(String rawUrlString) {return instance.getFormalizeUrl(rawUrlString);}@Overridepublic List getConnStrategyListByHost(String host) {String strategy = mIPStrategy.get(host);if (TextUtils.isEmpty(strategy)) {return instance.getConnStrategyListByHost(host);}final String[] ipPort = strategy.split(":");List list = new ArrayList();IConnStrategy connStrategy = new IConnStrategy() {@Overridepublic String getIp() {return ipPort[0];}@Overridepublic int getIpType() {return 0;}@Overridepublic int getIpSource() {return 0;}@Overridepublic int getPort() {return Integer.parseInt(ipPort[1]);}@Overridepublic ConnProtocol getProtocol() {return ConnProtocol.valueOf("http2", "0rtt", "emas", false);}@Overridepublic int getConnectionTimeout() {return 10000;}@Overridepublic int getReadTimeout() {return 10000;}@Overridepublic int getRetryTimes() {return 1;}@Overridepublic int getHeartbeat() {return 0;}};list.add(connStrategy);return list;}@Overridepublic String getSchemeByHost(String host) {return instance.getSchemeByHost(host);}@Overridepublic String getSchemeByHost(String host, String dftScheme) {return instance.getSchemeByHost(host, dftScheme);}@Overridepublic String getCNameByHost(String host) {return instance.getCNameByHost(host);}@Overridepublic String getClientIp() {return instance.getClientIp();}@Overridepublic void notifyConnEvent(String host, IConnStrategy connStrategy, ConnEvent connEvent) {instance.notifyConnEvent(host, connStrategy, connEvent);}@Overridepublic String getUnitByHost(String s) {return null;}@Overridepublic void forceRefreshStrategy(String host) {instance.forceRefreshStrategy(host);}@Overridepublic void registerListener(IStrategyListener listener) {instance.registerListener(listener);}@Overridepublic void unregisterListener(IStrategyListener listener) {instance.unregisterListener(listener);}});}/********************HA SDK END **************************/
}
到这里基本结束了,下面附上我的github上的demo
https://github.com/gitwangyang/SophixEMASDemo.git
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
