Android的在线热更新方案的实现

特别需要注意配置合适的Gradle版本
参考的文章:https://blog.csdn.net/qq_15527709/article/details/116144676
Robust官网:https://github.com/Meituan-Dianping/Robust
Robust问题讨论:https://github.com/Meituan-Dianping/Robust/issues/439


1、Android工程的Gradle配置:

01.Project的build.gradle:

buildscript {  //使用低版本的kotlinext.kotlin_version = "1.3.72"repositories {google()jcenter()}dependencies {//只能使用低版本的Gradleclasspath "com.android.tools.build:gradle:3.6.4"classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"classpath 'com.meituan.robust:gradle-plugin:0.4.99'classpath 'com.meituan.robust:auto-patch-plugin:0.4.99'// NOTE: Do not place your application dependencies here; they belong// in the individual module build.gradle files}
}allprojects {repositories {google()jcenter() // Warning: this repository is going to shut down soon//必须使用这个maven库maven { url 'https://jitpack.io' }}
}

2.app下的build.gradle(添加robust依赖):

dependencies {implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"//下面的版本号都要改implementation 'androidx.core:core-ktx:1.3.2'implementation 'androidx.appcompat:appcompat:1.2.0'implementation 'com.google.android.material:material:1.3.0'implementation 'androidx.constraintlayout:constraintlayout:2.0.4'.....//这是需要添加的依赖implementation 'com.meituan.robust:robust:0.4.99'implementation 'com.github.tbruyelle:rxpermissions:0.12'implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'implementation 'io.reactivex.rxjava3:rxjava:3.0.5'implementation 'com.android.support:multidex:1.0.3'

3.app下的build.gradle(针对Build Apk[命令:gradlew clean assembleRelease --stacktrace --no-daemon也可以buildApk]时可能的报错):

    defaultConfig {applicationId "com.huye.robusttest3"minSdkVersion 16targetSdkVersion 30versionCode 1versionName "1.0"//这里需要添加multiDexEnabled truetestInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"//报错重复androidsupportmultidexversion.txt时添加packagingOptions {exclude 'androidsupportmultidexversion.txt'}}

4.app下的build.gradle(完整配置):

plugins {id 'com.android.application'//打补丁使用auto-patch-plugin
//    id 'auto-patch-plugin'//获取初始版本的Apk使用robustid 'robust'id 'kotlin-android'
}android {compileSdkVersion 30buildToolsVersion "30.0.3"defaultConfig {applicationId "com.huye.robusttest3"minSdkVersion 16targetSdkVersion 30versionCode 1versionName "1.0"multiDexEnabled truetestInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"packagingOptions {exclude 'androidsupportmultidexversion.txt'}}signingConfigs {debug {keyAlias "key0"keyPassword "123456"storeFile file('robustsign2')storePassword "123456"}release {keyAlias "key0"keyPassword "123456"storeFile file('robustsign2')storePassword "123456"}}buildTypes {release {minifyEnabled trueproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'signingConfig signingConfigs.release}debug {minifyEnabled trueproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'signingConfig signingConfigs.debug}}compileOptions {sourceCompatibility JavaVersion.VERSION_1_8targetCompatibility JavaVersion.VERSION_1_8}kotlinOptions {jvmTarget = '1.8'}
}dependencies {implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"//这个版本号也要改implementation 'androidx.core:core-ktx:1.3.2'implementation 'androidx.appcompat:appcompat:1.2.0'implementation 'com.google.android.material:material:1.3.0'implementation 'androidx.constraintlayout:constraintlayout:2.0.4'testImplementation 'junit:junit:4.+'androidTestImplementation 'androidx.test.ext:junit:1.1.2'androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'implementation 'com.meituan.robust:robust:0.4.99'implementation 'com.github.tbruyelle:rxpermissions:0.12'implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'implementation 'io.reactivex.rxjava3:rxjava:3.0.5'implementation 'com.android.support:multidex:1.0.3'
}

2、AndroidManifest.xml需要添加的动态权限:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"package="com.huye.robusttest3"><uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.RobustTest3"tools:ignore="HardcodedDebugMode"><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>

3、添加robust.xml(注意修改包名):

<?xml version="1.0" encoding="utf-8"?>
<resources><switch><!--true代表打开Robust,请注意即使这个值为true,Robust也默认只在Release模式下开启--><!--false代表关闭Robust,无论是Debug还是Release模式都不会运行robust--><turnOnRobust>true</turnOnRobust><!--<turnOnRobust>false</turnOnRobust>--><!--是否开启手动模式,手动模式会去寻找配置项patchPackname包名下的所有类,自动的处理混淆,然后把patchPackname包名下的所有类制作成补丁--><!--这个开关只是把配置项patchPackname包名下的所有类制作成补丁,适用于特殊情况,一般不会遇到--><!--<manual>true</manual>--><manual>false</manual><!--是否强制插入插入代码,Robust默认在debug模式下是关闭的,开启这个选项为true会在debug下插入代码--><!--但是当配置项turnOnRobust是false时,这个配置项不会生效--><!--<forceInsert>true</forceInsert>--><forceInsert>false</forceInsert><!--是否捕获补丁中所有异常,建议上线的时候这个开关的值为true,测试的时候为false--><catchReflectException>true</catchReflectException><!--<catchReflectException>false</catchReflectException>--><!--是否在补丁加上log,建议上线的时候这个开关的值为false,测试的时候为true--><!--<patchLog>true</patchLog>--><patchLog>false</patchLog><!--项目是否支持progaurd--><proguard>true</proguard><!--<proguard>false</proguard>--><!--项目是否支持ASM进行插桩,默认使用ASM,推荐使用ASM,Javaassist在容易和其他字节码工具相互干扰--><useAsm>true</useAsm><!--<useAsm>false</useAsm>--><!--针对Java8级别的Lambda表达式,编译为private级别的javac函数,此时由开发者决定是否进行插桩处理--><forceInsertLambda>true</forceInsertLambda><!--        <forceInsertLambda>false</forceInsertLambda>--></switch><!--需要热补的包名或者类名,这些包名下的所有类都被会插入代码--><!--这个配置项是各个APP需要自行配置,就是你们App里面你们自己代码的包名,这些包名下的类会被Robust插入代码,没有被Robust插入代码的类Robust是无法修复的--><packname name="hotfixPackage"><name>com.huye.robusttest3</name></packname><!--不需要Robust插入代码的包名,Robust库不需要插入代码,如下的配置项请保留,还可以根据各个APP的情况执行添加--><exceptPackname name="exceptPackage"></exceptPackname><!--补丁的包名,请保持和类PatchManipulateImp中fetchPatchList方法中设置的补丁类名保持一致( setPatchesInfoImplClassFullName("com.meituan.robust.patch.PatchesInfoImpl")),各个App可以独立定制,需要确保的是setPatchesInfoImplClassFullName设置的包名是如下的配置项,类名必须是:PatchesInfoImpl--><patchPackname name="patchPackname"><name>com.huye.robusttest3</name></patchPackname><!--自动化补丁中,不需要反射处理的类,这个配置项慎重选择--><noNeedReflectClass name="classes no need to reflect"></noNeedReflectClass>
</resources>

4、创建MainActivity:

class MainActivity : AppCompatActivity() {lateinit var textView: TextViewoverridefun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)textView = findViewById(R.id.content_tv)val file =File(externalCacheDir?.absolutePath + File.separator + "robust" + File.separator + "patch ")if (!file.exists()) {file.mkdirs()}RxPermissions(this).request(Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE).subscribe { granted ->}}fun getString(): String {return "这是个Bug"}fun loadPatch(view: View) {PatchExecutor(this, PatchManipulateImp(), object : RobustCallBack {override fun onPatchListFetched(result: Boolean,isNet: Boolean,patches: MutableList<Patch>?) {}override fun onPatchFetched(result: Boolean, isNet: Boolean, patch: Patch?) {Log.d("swt", "onPatchFetched")}override fun onPatchApplied(result: Boolean, patch: Patch?) {Log.d("swt", "onPatchApplied")}override fun logNotify(log: String?, where: String?) {Log.d("swt", "logNotify")}override fun exceptionNotify(throwable: Throwable?, where: String?) {Log.d("swt", "exceptionNotify")}}).start()}@Modifyfun setTV(view: View) {textView.text = getString()}@Addfun getString1(): String {Toast.makeText(this, "终于成功了", Toast.LENGTH_SHORT).show()return "哈哈"}
}

5、创建PatchManipulateImp补丁执行类:

class PatchManipulateImp : PatchManipulate() {override fun fetchPatchList(context: Context): MutableList<Patch> {val patch = Patch()patch.name = "test"patch.tempPath =context.externalCacheDir?.absolutePath + File.separator + "robust" + File.separator + "patch"patch.localPath =context.externalCacheDir?.absolutePath + File.separator + "robust" + File.separator + "patch"patch.patchesInfoImplClassFullName = "com.huye.robusttest3.PatchesInfoImpl"val list = arrayListOf<Patch>()list.add(patch)return list}override fun verifyPatch(context: Context?, patch: Patch?): Boolean {return true}override fun ensurePatchExist(patch: Patch?): Boolean {return true}
}

6、制作patch补丁的步骤:

01.获取初始版本的Apk,将生成的mapping.text、methodsMap.robust、robust.apkhash放到app下的robust文件夹下面

02.切换build.gradle的插件,开始制作补丁

03.将patch.jar利用adb push放到指定的位置

adb push C:\Users\huye5\Desktop\test\patch.jar /sdcard/Android/data/com.huye.robusttest3/cache/robust/patch_temp.jar

04.加载补丁文件,观看Log日志输入是否正常,出现"apply result true"就是成功了


05.Demo

https://download.csdn.net/download/huye930610/36773423

Android的在线热更新方案_Robust相关推荐

  1. android热更新插件,与Android热更新方案Amigo的再次接触

    Amigo 作为一个"过气"的的热修复框架,用来学习和了解一下热修复的基本原理还是很好的.本文是本系列的第三篇. 前两篇: 与Android 热更新方案Amigo的初次接触 原作者 ...

  2. Android热更新方案Robust

    美团•大众点评是中国最大的O2O交易平台,目前已拥有近6亿用户,合作各类商户达432万,订单峰值突破1150万单.美团App是平台主要的入口之一,O2O交易场景的复杂性决定了App稳定性要达到近乎苛刻 ...

  3. android 热更新 方案,与Android热更新方案Amigo的初次接触

    主要记下引入Amigo的过程. 修复前:点击文字没有跳转 修复后:点击文字可以跳转(增加了Activity和布局文件) 其实热更新最重要的是不需要重新安装apk,有的甚至不需要重启app,就可以更新代 ...

  4. 移动端热更新方案(iOS+Android)

    PPT资源包含iOS+Android 各种方案分析:https://github.com/qiyer/Share/blob/master/%E7%83%AD%E6%9B%B4%E6%96%B0%E5% ...

  5. C#热更新方案的选择

    前项目的C#热更方案 小甜甜的C#热更方案 前段时间 noodle 说他把 小甜甜 项目中他做的 C#热更方案 开源了. 这个方案是一个 骚操作,不过是针对 il2cpp 的,核心思想是更新 libi ...

  6. Android 美团Robust热更新 使用入门

    Android热更新方案Robust 相信很多人都认识了解过 热修复.热更新.热补丁(对于这个技术也没有特别标准的一种叫法,下面我统一叫热更新),之后的一年里,各种热更新方案如雨后春笋般出现,比较耳熟 ...

  7. 腾讯开源手游热更新方案,Unity3D下的Lua编程

    写在前面 \\ xLua是Unity3D下Lua编程解决方案,自2016年初推广以来,已经应用于十多款腾讯自研游戏,因其良好性能.易用性.扩展性而广受好评.现在,腾讯已经将xLua开源到GitHub. ...

  8. Unity3D 热更新方案(集合各位专家的汇总)

    http://blog.csdn.net/guofeng526/article/details/52662994 热更新"这个词,在Unity3D的应用下,是有些语义错误的,但是作为大家都熟 ...

  9. uni-app整包更新与热更新方案(安卓和IOS)

    原文链接:uni-app整包更新与热更新方案(安卓和IOS) 效果预览 大致效果: 打开App,进入首页(首次),检测线上是否存在新版本,如果存在,弹窗提示用户是否进行版本更新.Android 有热更 ...

  10. 热更新方案-难不难在于你

    App热更新方案  为什么要做热更新 当一个App发布之后,突然发现了一个严重bug需要进行紧急修复,这时候公司各方就会忙得焦头烂额:重新打包App.测试.向各个应用市场和渠道换包.提示用户升级.用户 ...

最新文章

  1. 【面试】我是如何在面试别人Spring事务时“套路”对方的
  2. python发邮件包含表格,在Python中在电子邮件正文中包含Excel表
  3. Java实用教程笔记 子类与继承
  4. join为什么每个字符都分割了 js_JS截取与分割字符串常用技巧总结
  5. 笔记-中项案例题-2017年上-计算题
  6. 异想-天开 python---while、for、if-else 循环学习
  7. 高级指引——自定义节点
  8. Bootstrap组件_分页
  9. Highly Available (Mirrored) Queues
  10. Pad和Margin
  11. FindBugs Maven插件教程
  12. REST与RESTful
  13. 简单的小愿望,就这么难实现
  14. ITIL 4知识系列之ITIL4的设计框架解析
  15. MLDN出品JAVA风暴终极的java学习视频
  16. python如何解压zip文件_Python压缩解压zip文件
  17. Android 自动旋转屏幕总结
  18. 扶桑之伤 作者:长铗
  19. 离散数学知识点总结(2):命题公式的类型
  20. Python是信奥的基础吗,学习信奥要不要先学python

热门文章

  1. python最新抢票脚本
  2. excel批量添加超级链接
  3. SQL Server中关于跟踪(Trace)那点事
  4. 多御浏览器安卓版有哪些地方值得下载使用?
  5. python画图像_使用python绘制SDSS图像
  6. 这5个是不是元宇宙游戏遗珠?
  7. 数据库系统概论(第5版)王珊 详细知识清单 期末复习速成 考前冲刺 面试——(第一篇 基础篇)
  8. Result window is too large, from + size must be less than or equal to: [10000]
  9. Android中的临时文件
  10. 永久挂载光盘镜像及本地yum源搭建