Sophix官网文档地址

https://help.aliyun.com/document_detail/53240.html

快速接入

项目build.gradle的repositories节点下添加

maven{
url "http://maven.aliyun.com/nexus/content/repositories/releases"
}

app目录build.gradle的dependencies节点下添加

    implementation 'com.aliyun.ams:alicloud-android-hotfix:3.2.4'

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"/>

标签里添加

    <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密钥" />

App ID、App Secret和RSA密钥在阿里云控制台获取,控制台传送门



点击添加产品,然后添加应用



应用创建完,点击 移动热修复-应用信息 可以看到所需的App ID、App Secret和RSA密钥





需要注意的是,AppKey不是App ID,AppKey加上"-1"才是App ID,即25053496-1才是需要的App ID,可以下载如下文件查看App ID

Application配置如下

package com.example.zachary.sophix;

import android.app.Application;
import android.content.Context;
import com.taobao.sophix.PatchStatus;
import com.taobao.sophix.SophixManager;
import com.taobao.sophix.listener.PatchLoadStatusListener; public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
// queryAndLoadNewPatch不可放在attachBaseContext 中,否则无网络权限,建议放在后面任意时刻,如onCreate中
SophixManager.getInstance().queryAndLoadNewPatch();
} @Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
// initialize必须放在attachBaseContext最前面,初始化代码直接写在Application类里面,切勿封装到其他类。
SophixManager.getInstance().setContext(this)
.setAppVersion("1.0.0")
.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自杀,以此加快应用补丁,详见1.3.2.3
} else {
// 其它错误信息, 查看PatchStatus类说明
}
}
}).initialize();
}
}

这样就配置完了,接下来测试一下,在activity布局文件随便写几个字然后打包安装到手机

然后改一下布局文件,再次打包

下载补丁生成器,地址:https://help.aliyun.com/document_detail/53247.html?spm=a2c4g.11186623.6.552.76dc4122Tgu7um



选择两次打包的apk,点击 GO! 生成补丁

打开控制台,点击 移动热修复-补丁管理-上传补丁



上传完补丁,点击详情



点击新建发布,选择全量发布,(灰色发布大概是随机选择几个目标测试,减少风险)



发布成功后,杀掉刚才安装带有“天王盖地虎”内容的安装包,重新打开,发现内容变成“宝塔镇河妖”,说明热修复成功!

稳健接入

稳健接入快速接入的差异主要在Application的配置上,其他配置都一样,新建一个SophixStubApplication类,配置如下

package com.example.zachary.sophix;

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;
/**
* Sophix入口类,专门用于初始化Sophix,不应包含任何业务逻辑。
* 此类必须继承自SophixApplication,onCreate方法不需要实现。
* 此类不应与项目中的其他类有任何互相调用的逻辑,必须完全做到隔离。
* AndroidManifest中设置application为此类,而SophixEntry中设为原先Application类。
* 注意原先Application里不需要再重复初始化Sophix,并且需要避免混淆原先Application类。
* 如有其它自定义改造,请咨询官方后妥善处理。
*/
public class SophixStubApplication extends SophixApplication {
private final String TAG = "SophixStubApplication";
//此处SophixEntry应指定真正的Application,并且保证RealApplicationStub类名不被混淆。
@Keep
@SophixEntry(MyRealApplication.class)
static class RealApplicationStub {}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
//如果需要使用MultiDex,需要在此处调用。
//MultiDex.install(this);
initSophix();
}
private void initSophix() {
String appVersion = "1.0.0";//和build.gradle配置的要一致
try {
appVersion = this.getPackageManager()
.getPackageInfo(this.getPackageName(), 0)
.versionName;
} catch (Exception e) {
}
final SophixManager instance = SophixManager.getInstance();
instance.setContext(this)
.setAppVersion(appVersion)
.setSecretMetaData(null, null, null)
.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();
}
}

MyRealApplication就是我们项目中自己的Application,需要在onCreate里添加如下代码

public class MyRealApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
//queryAndLoadNewPatch不可放在attachBaseContext 中,否则无网络权限,建议放在后面任意时刻,如onCreate中
SophixManager.getInstance().queryAndLoadNewPatch();
}
}

然后在AndroidManifest.xml中声明SophixStubApplication记住是SophixStubApplication,而不是项目本来的Application,这跟微信的热修复框架Tinker有点类似啊哈哈~~

项目已上传Github: https://github.com/Zachary46/Sophix

Android最火热修复实战的更多相关文章

  1. C# Xamarin For Android自动升级项目实战

    一.课程介绍 “明人不说暗话,跟着阿笨一起玩Xamarin”,本次分享课程阿笨将带来大家一起学习Xamarin For Android系列<C# Xamarin For Android自动升级项 ...

  2. Android JNI学习(二)——实战JNI之“hello world”

    本系列文章如下: Android JNI(一)——NDK与JNI基础 Android JNI学习(二)——实战JNI之“hello world” Android JNI学习(三)——Java与Nati ...

  3. 【Android自己定义View实战】之自己定义超简单SearchView搜索框

    [Android自己定义View实战]之自己定义超简单SearchView搜索框 这篇文章是对之前文章的翻新,至于为什么我要又一次改动这篇文章?原因例如以下 1.有人举报我抄袭,原文链接:http:/ ...

  4. 破解CentOS7的root及加密grub修复实战

    破解CentOS7的root及加密grub修复实战 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.破解CentOS7的root口令方案1 1>.启动时任意键暂停启动 2& ...

  5. AndFix热修复 —— 实战与源码解析

    当你的应用发布后第二天却发现一个重要的bug要修复,头疼的同时你可能想着赶紧修复重新打个包发布出去,让用户收到自动更新重新下载.但是万事皆有可能,万一隔一天又发现一个急需修复的bug呢?难道再次发布打 ...

  6. Android UI性能优化实战, 识别View中的性能问题

    出自:[张鸿洋的博客]来源:http://blog.csdn.net/lmj623565791/article/details/45556391 1.概述 2015年初google发布了Android ...

  7. android学习视频(实战项目演练)

    1.基于Android平台实战无线点餐系统(客户端(Client)和服务端(Server))①http://kuai.xunlei.com/d/xmBrDwI8CAAyXVFRa3d②http://k ...

  8. Android网络框架Volley(实战篇)

      之前讲了ym—— Android网络框架Volley(体验篇),大家应该了解了volley的使用,接下来我们要看看如何把volley使用到实战项目里面,我们先考虑下一些问题: 从上一篇来看 mQu ...

  9. 初步探究Android App API接口测试--实战

    一.Android App API接口测试 1.如何学好Android App API接口测试 postman可以用来实现API接口自动化测试,但是也有弊端,无法实现接口测试数据的参数化,为了达到接口 ...

随机推荐

  1. windows下手动安装composer并配置环境变量

    windows下手动安装composer并配置环境变量   转载地址: https://my.oschina.net/7sites/blog/209997 之前发表过一篇如何为composer设置代理 ...

  2. C# readonly与const区别

    静态常量:是指编译器在编译时候会对常量进行解析,并将常量的值替换成初始化的那个值. 动态常量的值则是在运行的那一刻才获得的,编译器编译期间将其标示为只读常量,而不用常量的值代替,这样动态常量不必在声明 ...

  3. ECMAScript课程

    ECMAScript的语法使用      https://blog.csdn.net/m0_37452696/article/details/78370504 ECMAScript 6简介说明   h ...

  4. Unity日常记录-本地保存未来时间实现倒计时

    本地保存未来时间实现倒计时 TimeTool工具类:获取当前时间.未来时间.两时间差 using System; using UnityEngine; public class TimeTool { ...

  5. hbuilder + 夜神模拟器

    1. 安装hbuilder.夜神模拟器 2. 将夜神模拟器设为手机版,启用急速模式 3. 打开夜神模拟器设置,进入关于手机,点击版本号启用开发者模式 4. 进入开发者模式设置,启用usb调试 5. h ...

  6. 业务限流场景简单实现方案:RateLimiter

    前因:因为本系统中,有大数据高并发的场景.在向下游系统发送请求的时候,需要限流.否则会造成下游系统的堵塞. 实现方案1: Thread.sleep(ms). 优点:简单粗暴,一行代码搞定 缺点:有点l ...

  7. c#数据库事务锁类型

    一.脏读.不可重复读.幻象读的区别   1.脏读:包含未提交数据的读取.例如,事务 a 更改了某行(数据库已发生更改,但尚未提交,有可能发生回滚),事务 b 在事务 a 提交更改之前读取已更改的行.如 ...

  8. Struts 2 概念介绍

    概念引入 Web层通常使用Servlet+jsp,现在使用Struts2来处理访问服务器请求 Service层 目前使用JavaBean Dao层目前使用Hibernate Spring是一个大的管家 ...

  9. 牛客 黑龙江大学程序设计竞赛重现 19-4-25 D

    题意: n项工作 1~n  工时s[i] ~e[i], 工时有覆盖的工作不能被同一台机器同时操作, 问完成所有工作的最少机器数 思路:前缀差分和 e.g. a            2 3 4    ...

  10. Windows Server 2012 R2 英文版安装中文语言包教程

    Windows Server 是云操作系统的主要组成部分. 有了 Windows Server,再加上云操作系统内的开发者技术,您就可以构建现代业务应用程序. 现代业务应用程序通常涵盖内部部署资源和公 ...