Android 腾讯 Bugly 热修复
依赖配置流程
Bugly 文档中心
引入依赖
- 在项目的 build.gradle 中加入依赖
buildscript {repositories {jcenter()google()}dependencies {//...classpath "com.tencent.bugly:tinker-support:1.1.5"}
}
- 在项目 app 中加入依赖 ( 之前引入过的 bugly 异常捕获和应用升级的依赖可以直接注释掉,下面依赖已经包含了)
compile 'com.android.support:multidex:1.0.0' //有了就不需要再加了compile 'com.tencent.bugly:crashreport_upgrade:1.3.6'// 指定tinker依赖版本(注:应用升级1.3.5版本起,不再内置tinker)compile 'com.tencent.tinker:tinker-android-lib:1.9.9'compile 'com.tencent.bugly:nativecrashreport:3.7.1'
tinker 配置
- 在 app 文件夹的根目录新建 tinker-support.gradle 文件内容如下(建议直接复制)
apply plugin: 'com.tencent.bugly.tinker-support'def bakPath = file("${buildDir}/bakApk/")/*** 此处填写每次构建生成的基准包目录*/
def baseApkDir = "app-1024-16-15-32"/*** 对于插件各参数的详细解析请参考*/
tinkerSupport {// 开启tinker-support插件,默认值trueenable = true// 指定归档目录,默认值当前module的子目录tinkerautoBackupApkDir = "${bakPath}"//建议设置true,用户就不用再自己管理tinkerId的命名,插件会为每一次构建的base包自动生成唯一的tinkerId,默认命名规则是versionname.versioncode_时间戳//具体参考https://github.com/BuglyDevTeam/Bugly-Android-Demo/wiki/Tinker-ID%E8%AF%A5%E6%80%8E%E4%B9%88%E8%AE%BE%E7%BD%AE
// autoGenerateTinkerId = true//tinkerId必须保证唯一性,如果两个base包的tinkerid是一样的,并且都联网激活了,那么后续补丁上传到后台的时候会出现匹配错误
// tinkerId = "if autoGenerateTinkerId=true ,no need set here"// 是否启用覆盖tinkerPatch配置功能,默认值false// 开启后tinkerPatch配置不生效,即无需添加tinkerPatchoverrideTinkerPatchConfiguration = true// 编译补丁包时,必需指定基线版本的apk,默认值为空// 如果为空,则表示不是进行补丁包的编译// @{link tinkerPatch.oldApk }baseApk = "${bakPath}/${baseApkDir}/app-release.apk"// 对应tinker插件applyMappingbaseApkProguardMapping = "${bakPath}/${baseApkDir}/app-release-mapping.txt"// 对应tinker插件applyResourceMappingbaseApkResourceMapping = "${bakPath}/${baseApkDir}/app-release-R.txt"// 构建基准包和补丁包都要指定不同的tinkerId,并且必须保证唯一性tinkerId = "v1.8.5_patch_1"// 构建多渠道补丁时使用// buildAllFlavorsDir = "${bakPath}/${baseApkDir}"// 是否启用加固模式,默认为false.(tinker-spport 1.0.7起支持)// isProtectedApp = true// 是否开启反射Application模式enableProxyApplication = true// 是否支持新增非export的Activity(注意:设置为true才能修改AndroidManifest文件)supportHotplugComponent = true}/*** 一般来说,我们无需对下面的参数做任何的修改* 对于各参数的详细介绍请参考:* https://github.com/Tencent/tinker/wiki/Tinker-%E6%8E%A5%E5%85%A5%E6%8C%87%E5%8D%97*/
tinkerPatch {//oldApk ="${bakPath}/${appName}/app-release.apk"ignoreWarning = falseuseSign = truedex {dexMode = "jar"pattern = ["classes*.dex"]loader = []}lib {pattern = ["lib/*/*.so"]}res {pattern = ["res/*", "r/*", "assets/*", "resources.arsc", "AndroidManifest.xml"]ignoreChange = []largeModSize = 100}packageConfig {}sevenZip {zipArtifact = "com.tencent.mm:SevenZip:1.1.10"
// path = "/usr/local/bin/7za"}buildConfig {keepDexApply = false//tinkerId = "1.0.1-base"//applyMapping = "${bakPath}/${appName}/app-release-mapping.txt" // 可选,设置mapping文件,建议保持旧apk的proguard混淆方式//applyResourceMapping = "${bakPath}/${appName}/app-release-R.txt" // 可选,设置R.txt文件,通过旧apk文件保持ResId的分配}
}
- 在 app 的 build.gradle 加入 apply from: ‘tinker-support.gradle’ 这个配置文件
apply plugin: 'com.android.application'
apply from: 'tinker-support.gradle'
android {//...
}
项目配置
这里我只说一种可以改 Application 的入侵性比较弱一点的方式,但是相对没那么稳定:)
- Application 配置( Bugly 获取 appId 这里就不说怎么弄的了吧),记得引用这个 Application
@Overridepublic void onCreate() {super.onCreate();//热修复initBetaHotfix();}@Overrideprotected void attachBaseContext(Context base) {super.attachBaseContext(base);MultiDex.install(this);}//热更新private void initBetaHotfix() {// 设置是否开启热更新能力,默认为trueBeta.enableHotfix = true;// 设置是否自动下载补丁,默认为trueBeta.canAutoDownloadPatch = true;// 设置是否自动合成补丁,默认为trueBeta.canAutoPatch = true;// 设置是否提示用户重启,默认为falseBeta.canNotifyUserRestart = false;// 安装tinkerBeta.installTinker();// 设置开发设备,默认为false,上传补丁如果下发范围指定为“开发设备”,需要调用此接口来标识开发设备Bugly.setIsDevelopmentDevice(this, true);// 调试时,将第三个参数改为trueBugly.init(this, Config.BUGLY_ID, true);//异常捕获CrashReport.initCrashReport(getApplicationContext(), Config.BUGLY_ID, false);}
- AndroidManifest.xml 文件配置,不考虑 bugly 热修复依赖版本太低问题,不引入 FileProvider 相关配置
<activityandroid:name="com.tencent.bugly.beta.ui.BetaActivity"android:configChanges="keyboardHidden|orientation|screenSize|locale"android:theme="@android:style/Theme.Translucent" />
添加权限
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<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_LOGS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
配置到这里就完成啦
----------------------------------------- 华丽的分割 -----------------------------------------
打包流程
打包流程主要分成两个一个是打基包,一个是打补丁包
打基包
指定一个版本的基包例如 v1.8.5 版本的基包
- 在之前配置好的 tinker-support.gradle 文件下修改 tinkerId 例如: tinkerId = “v1.8.5_base” 注意:这里的thinkerId 要保证在你之前发过的版本里是唯一的,这样我们的补丁包才可以检测匹配到
- 点击左边标签 (Gradle)选择 项目名 > :app > Tasks > build > assembleRelease 运行(注意:如果没有启用混淆或者没有签名会出错,必须启用混淆并且签名)
- 运行完成后,在 app > build > bakApk > app-xxxx-xx-xx-xx 里面有三个文件,分别为: tinker-support.gradle 配置里设置的三个文件名(如果没有 app-release-mapping.txt 文件的话有可能是你没有启用混淆,或者是你的混淆文件有问题)
- 将 app-1024-16-15-32(命名规则 月日-小时-分-秒) 这个文件夹存档(因为后面你 clean 项目或者 rebuild 项目这个文件会消失)后面我们打包补丁包的时候需要用到
通过以上步骤就完成了基包的打包(直接将这个包发到各大应用商城,不说分渠道打包)
打包补丁包
- 先把你想要打补丁的基包文件(上面的 app-1024-16-15-32 文件夹)放到 app > build > bakApk 文件夹下,如果没有 bakApk 文件夹就新建一个。
- copy 你基包文件夹名称 eg: app-1024-16-15-32 然后黏贴到 tinker-support.gradle 配置文件的 def baseApkDir = “基包文件夹名称”
- 在这个配置文件修改 tinkerId (跟上面基类包一样 需要唯一)规则你自己来定
- 生成补丁包,Gradle > 项目名 > app > Tasks > thinker_support > buildTinkerPatchRelease
- 生成的补丁包会在 app > bulid > outputs > patch > release 文件夹中,有三个 apk 文件这里我们需要用到的是 _7zip.apk 的 apk 文件
- 检查我们的补丁包,双击 patch_signed_7zip.apk 文件 会有一个 YAPATCH.MF 文件,点击这个文件就可以查看你的补丁包的一些信息,他是通过匹配到基包的 thinkId 去下发补丁包的,下面 tinkerId 打错了(懒得改)
- 接下来就可以直接上 bugly 的官网上发布补丁了,如果你怕出错你可以先发一个测试设备的补丁包,没问题再发全量设备的补丁包。
注意点
- 项目需要签名打包
- 项目需要引入混淆配置 并打开
- 保留每次生成基类包的 apk , mapping , R 文件 还有 tinkerId (唯一)
- 每次生成 patch 补丁包的时候要修改 热修复配置文件的 tinkerId (需要唯一)
- 出现 tinker_intermediates\values_backup notfoundFile 的时候 clean 一下项目 然后把你之前基包文件(例如 app-1024-16-15-32 文件夹)放到 app > build > bakApk 文件夹下,如果没有 bakApk 文件夹就新建一个。
混淆文件问题
我们混淆文件可能会出现问题造成 app-release-mapping.txt 文件没有生成,在这里我直接给出一个比较万能的签名文件(你的其他库的混淆还有你自己混淆加再后面就行啦,bugly 的混淆我已经加到最后面了)
注意: 之前存在的一些库有需要加入混淆的都需要加上不然打包出来的安装包可能会报错
-keep public class com.android.vending.licensing.ILicensingService # 保持哪些类不被混淆
-keep public class com.google.vending.licensing.ILicensingService # 保持哪些类不被混淆-keepclassmembers class **.R$* {public static <fields>;public static final int *;
}
-keepclasseswithmembernames class * { # 保持 native 方法不被混淆native <methods>;
}
-keepclasseswithmembers class * { # 保持自定义控件类不被混淆public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {# 保持自定义控件类不被混淆public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * extends android.app.Activity { # 保持自定义控件类不被混淆public void *(android.view.View);
}
-keepclassmembers enum * { # 保持枚举 enum 类不被混淆public static **[] values();public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable { # 保持 Parcelable 不被混淆public static final android.os.Parcelable$Creator *;
}-keep public class * extends android.view.View {public <init>(android.content.Context);public <init>(android.content.Context, android.util.AttributeSet);public <init>(android.content.Context, android.util.AttributeSet, int);public void set*(...);}
-keepclassmembers public class * extends android.view.View {void set*(***);*** get*();
}#apk 包内所有 class 的内部结构
#-dump class_files.txt
#未混淆的类和成员
#-printseeds seeds.txt
#列出从 apk 中删除的代码
#-printusage unused.txt
#混淆前后的映射
#-printmapping mapping.txt#fastjson 可以混淆也可以不混淆
#-keep class javax.ws.rs.** { *; }
#-dontwarn com.alibaba.fastjson.**
#-keep class com.alibaba.fastjson.** { *; }
-keepclassmembers class * implements java.io.Serializable {static final long serialVersionUID;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();public <fields>;
}
-keepattributes Signature#gson
-dontwarn com.google.gson.**
-keep class com.google.gson.** { *;}
-keepclassmembers class * implements java.io.Serializable {static final long serialVersionUID;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();public <fields>;
}#v4
-dontwarn android.support.v4.**
-keep class android.support.v4.** { *; }
-keep interface android.support.v4.app.** { *; }
-keep public class * extends android.support.v4.**
-keep public class * extends android.app.Fragment#greendao
#-dontwarn de.greenrobot.dao.**
#-keep class de.greenrobot.dao.** { *;}
-keepclassmembers class * extends de.greenrobot.dao.AbstractDao {public static java.lang.String TABLENAME;
}
-keep class **$Properties# 对于带有回调函数的onXXEvent、**On*Listener的,不能被混淆
-keepclassmembers class * {void *(**On*Event);void *(**On*Listener);
}# webView处理,项目中没有使用到webView忽略即可
-keepclassmembers class fqcn.of.javascript.interface.for.webview {public *;
}
-keepclassmembers class * extends android.webkit.webViewClient {public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);public boolean *(android.webkit.WebView, java.lang.String);
}
-keepclassmembers class * extends android.webkit.webViewClient {public void *(android.webkit.webView, jav.lang.String);
}## Bugly混淆规则
-dontwarn com.tencent.bugly.**
-keep public class com.tencent.bugly.**{*;}
# tinker
-dontwarn com.tencent.tinker.**
-keep class com.tencent.tinker.** { *; }# 避免影响升级功能,需要keep住support包的类
#-keep class android.support.**{*;}
踩了一个坑,过来补充一下。
问题:继承了微信分享后没有引入依赖造成分享无法使用。
所以在要混淆文件中加入
-keep class com.tencent.mm.opensdk.** {*;}
-keep class com.tencent.wxop.** {*;}
-keep class com.tencent.mm.sdk.** {*;}
Android 腾讯 Bugly 热修复相关推荐
- 安卓开发腾讯Bugly热修复集成和使用思路
文章目录 一,官方集成 一.获取App ID 二.添加插件依赖 三.集成SDK 四.配置Tinker 1.overrideTinkerPatchConfiguration 2.baseApkDir 3 ...
- 腾讯Tinker 热修复 Andriod studio 3.0 配置和集成(二)多渠道打包和补丁发布
腾讯Tinker 热修复 Andriod studio 3.0 多渠道打包和发布补丁方式推荐 本文说明 在之前我已经分享了Tinker 热修复的 Andriod studio3.0 初次配置和集成,时 ...
- Bugly热修复之通过自建服务器管理补丁方案
Bugly热修复之通过自建服务器管理补丁方案 Bugly虽然提供补丁管理后台,但有时项目可能希望自行管理补丁,今天就简单说一下这个方案. 文章目录 Bugly热修复之通过自建服务器管理补丁方案 背景 ...
- Android 腾讯Bugly使用(异常上报,全量升级,热更新)
1.0.1腾讯Bugly使用(异常上报,全量升级,热更新) 说明 Bugly全量升级,热更新以及异常上报是一起集成的,还包括运营统计,本文档着重演示热更新功能. 接入步骤 1.在Project的bui ...
- Android 腾讯Bugly的应用升级热更新
经过去年的九月份至现在,发现自己很久没有写过比较好的文章了.今天就趁着通宵的劲,写一下对腾讯Bugly的应用升级&热更新的理解,希望对新手有所帮助,有兴趣的可以了解下,没兴趣的也可以看完之后吐 ...
- 腾讯Tinker 热修复 Andriod studio 3.0 配置和集成(一)
本文说明 面试的时候经常问我有没有用过热修复?用谁的?能说下原理吗?当时我回答得不好,毕竟以前的项目都没有用,又不敢装逼,mmp,但是基本流程还是知道的,所以我们来初探下Tinker 这个热修复,如果 ...
- 《android基于andFix的热修复方案》思路篇
1:需求背景 项目上线之后,发现BUG需要修复(比如安卓兼容性等测试难以发现的问题),频繁的更新影响用户体验 2:方案要求 静默下载,耗费流量少,打完补丁后立刻生效,不用重启apk 3:解决思路 3. ...
- Android App 线上热修复方案
热修复一词恐怕最早应用在微软.为了巩固其windows系统和office的市场占有率,微软开发并维护了一套线上修复方案,用于修复漏洞及特定问题(LDR),避免延续到发版解决(GDR),详见HotFix ...
- Android App 线上热修复方案Xposed
热修复一词恐怕最早应用在微软.为了巩固其windows系统和office的市场占有率,微软开发并维护了一套线上修复方案,用于修复漏洞及特定问题(LDR),避免延续到发版解决(GDR),详见HotFix ...
最新文章
- php中tables,php显示TABLE数据
- html填满剩余空间,html – 标题,两侧填充剩余空间
- R 多变量数据预处理_超长文详解:C语言预处理命令
- 网站制作---asp操作数据库的一个小例子
- UITableView的复用过程
- 【FPGA-F3】阿里云FAAS平台,极大简化FPGA开发部署流程 1
- 毕业论文格式系列---1.论文公式编号
- 计算机考研 外部排序,2021考研408数据结构基础知识点:外部排序
- 电信网关改造无线打印服务器,电信天翼网关路由改桥接流程
- pr怎么导出预设_怎样用Pr导出清晰度高的视频?
- PS的30个实用技巧大全
- BOM类型转换——>EBOM、MBOM、PBOM
- HDU4565 So Easy! (矩阵)
- android实现自动评论脚本,自动点击器评论器app下载
- MD5加密——原理介绍
- 路由器搭设mysql_搭建mysql5.7.13环境的方法步骤
- MindSpore联邦学习框架解决行业级难题
- 如何用C语言打印爱心图案 /爱心代码的实现
- 云服务器密码忘了_云服务器 root 密码忘记了怎么办
- 100例经典Python核心实战提升练习题汇总(三)