Bugly Android 热更新常见问题

Q:之前使用Tinker怎么切换过来使用Bugly?

A:Bugly使用源码集成Tinker,如果之前集成过Tinker,你需要注释掉以下配置:

//    compile("com.tencent.tinker:tinker-android-lib:${TINKER_VERSION}") { changing = true }
//    provided("com.tencent.tinker:tinker-android-anno:${TINKER_VERSION}") { changing = true } 

插件配置不需要更改,只需要加上我们Bugly额外的tinker-support插件即可:

     classpath "com.tencent.bugly:tinker-support:latest.release"

Q: 基线版本表示什么意思?

A:表示你需要修复apk的版本,比如你已经上线了某个版本的apk,你需要用一个唯一的tinkerId来标识这个版本,而补丁包也是基于这个版本打的。

Q:打一个补丁包需要改哪些东西?

A:

  1. 修复bug的类、修改资源
  2. 修改oldApk配置
  3. 修改tinkerId

Q:tinkerId该怎么填?

A:在运行过程中,我们需要验证基准apk包的tinkerId是否等于补丁包的tinkerId。这个是决定补丁包能运行在哪些基准包上面,一般来说我们可以使用git版本号、versionName等等。

Q:两次传入的tinkerId是否一样?

A:不一样的,编译补丁包时,tinker会自动读取基准包AndroidManifest的tinkerId作为package_meta.txt中的TINKER_ID。将本次编译传入的tinkerId,作为package_meta.txt的NEW_TINKER_ID。

Q. 为什么我上传补丁提示我“未匹配到可用补丁的App版本”?

A:如果你的基线版本没有上报过联网,基于这个版本生成的补丁包就无法匹配到,请检查你的基线版本配置是否正确。(具体参考:启动apk,上报联网数据)

Q. 我该上传哪个补丁?patch目录跟tinkerPatch目录下的补丁有什么区别吗?

A:你必须要上传build/outputs/patch目录下的补丁包,

Q:我以前的是Bugly SDK,现在集成升级SDK会有什么影响?

A:不会有影响的,升级SDK内置Bugly功能模块,你只需要将初始化方法改为统一的Bugly.init(getApplicationContext(), "注册时申请的APPID", false);即可。

Q:你们是怎么定义开发设备的?

A:我们会提供接口Bugly.setIsDevelopmentDevice(getApplicationContext(), true);,我们后台就会将你当前设备识别为开发设备,如果设置为false则非开发设备,我们会根据这个配置进行策略控制。

Q:如果我配置了升级策略,又配置了补丁策略,会是怎样的效果?

A:升级策略优先级会高于补丁策略,后台会优先下发升级策略。毕竟你都要升级了,热更新只是帮助你修复bug而已。

Q:我只想使用热更新,不想使用升级?

A:热更新是包含在升级SDK里面的,你可以不配置任何升级策略,只需按照热更新文档集成即可。

Q:是否支持加固模式?

A:

Bugly 1.3.0及以上版本支持(tinker 1.7.9)

需要你在tinker-support配置中设置isProtectedApp = true。

Q:是否支持打多Flavor的patch包 A:支持的。你需要配置productFlavor(示例):

  productFlavors {
        xiaomi {
        }

        yyb {
        }
    }

打flavor包,只需要配置构建buildAllFlavorsDir的目录,其他字段不需要填写(执行buildAllFlavorsTinkerPatchRelease就可以得到所有flavor的包):

打渠道补丁包配置

Q: 热补丁安全性,以及SDK针对应用补丁失败?

A:Bugly采用HTTPS来保证信息传输的安全性,Bugly会针对下载的补丁包进行签名计算来保证跟下发策略补丁包签名的一致性,如果补丁应用失败,我们会将补丁包直接清除,下次启动你还是可以拿到补丁策略信息。

Q: 是不是每次发版都要保留基准包、混淆配置文件、资源Id文件?

A:当然啦,你不保存基准包,我们打补丁怎么知道要基于哪个版本打补丁?所以建议大家每次发版注意保存基准apk包,还有对应编译生成的mapping文件和R.txt文件。

Q:完整的测试流程是怎样的?

A:

  • 打基准包安装并上报联网(注:填写唯一的tinkerId)
  • 对基准包的bug修复(可以是Java代码变更,资源的变更)
  • 修改基准包路径、修改补丁包tinkerId、mapping文件路径(如果开启了混淆需要配置)、resId文件路径
  • 执行buildTinkerPatchRelease打Release版本补丁包
  • 选择app/build/outputs/patch目录下的补丁包并上传(注:不要选择tinkerPatch目录下的补丁包,不然上传会有问题
  • 编辑下发补丁规则,点击立即下发
  • 杀死进程并重启基准包,请求补丁策略(SDK会自动下载补丁并合成)
  • 再次重启基准包,检验补丁应用结果
  • 查看页面,查看激活数据的变化

Q: 集成热更新之后出现以下错误

Error:A problem occurred configuring project ':app'. Failed to notify project evaluation listener. Tinker does not support instant run mode, please trigger build by assembleDebug or disable instant run in 'File->Settings...'. can't find tinkerProcessDebugManifest, you must init tinker plugin first!

A: tinker不支持instant run模式,你需要找到File->Settings->Build,Execution,Deployment->instant run并关闭,日常调试可以tinker关闭来使用instant run。

Q: 日常调试需要使用instant run,怎么关闭tinker

A:这里分两种情况:

使用反射Application方式接入:可以直接在build.gradle中将apply from: 'tinker-support.gradle'注释掉。

改造Application方式接入:先将tinkerSupport中overrideTinkerPatchConfiguration设置为false 修改成将tinkerSupport中enable设置为false。 

Q:如果我打了多个补丁包,比如先上传了补丁A已经下发到了设备中并且修复,如果我又打了一个补丁,这种情况会怎样?

A:如果你的基于基线版本打了多个补丁包,并且上传了多个,我们会以你最后上传的补丁为准,就是说后面的补丁会覆盖前面的补丁。

Q: 自定义下发条件该怎么填

A:自定义只允许输入 > 、> =、=、< 、< = 及数字、小数点、分号(;) 比如只允许下发系统版本大于等于5.0设备和小于等于7.0设备 :>= 5.0;<=7.0

Q:为什么收不到补丁, 下发的时间要多长?

A: 请检查您设置补丁的下发范围,如果选择的是开发设备,要检查你是否调用了Bugly.setIsDevelopmentDevice(getApplicationContext(), true);,否则你需要检查当前版本tinkerId是否匹配补丁的对应的基线版本tinkerId.

Q: 补丁什么时候生效?

A: 您需要杀死当前app进程,重新启动之后即可生效。

Q:我集成了热更新SDK,还需要集成异常上报的SDK?

A: 您只需要集成热更新, 无须再集成异常上报SDK。

Q: 打补丁包出现异常,提示:loader classes in old primary dex are mismatched to those in new primary dex

A: 如果出现这样的异常,可能是因为SDK版本升级导致loader类变更,tinker在打补丁包会检查loader是否发生变更并且会抛出异常,建议大家保持基线版本所用的sdk版本,比如基线版本代码用到的sdk版本是1.2.5,那么打补丁的版本也应该保持1.2.5版本。

Q: 为什么打印出来的tinkerId会为null?

A:

1.改造application方式集成: 看beta.installtinker(this);是不是没有添加参数this

2.反射方式集成: 看tinker-support.gradle中 反射模式是否设置为true

Q: 为什么我打基准包没有生成mapping文件?是否必须要

A: 开启混淆才会生成mapping文件,非必需

Q:为什么我的补丁包上传不了?

A:

1.基准包联网(bugly.init初始化第三个参数设置为true,通过查看logcat中搜索tinkerid 看base tinkeid是否为null)

2.必需上传patch目录下的补丁包

3.补丁包是不是针对对你手机安装联网的基准包所打的

Q:补丁下发后出现如下异常:com.tencent.tiker.loader.TinkerRuntimeException:Tinker Exception:can’t recognize dex mode:xxxxx.,jar

A: 原因 升级sdk和tinker-support插件不对应。https://bugly.qq.com/docs/release-notes/release-android-beta/?v=20171212190105 看对应关系。

Q:ignore warning is false,manifest was changed,while hot plug component support mode is disabled such changes will not take effect

A: 添加如下设置:

tinkerSupport {
    supportHotplugComponent = true
}

Q:为什么我的补丁包上传匹配到的不是我的基准包版本?

A:

原因:你之前测试时使用过和当前基准包版本一样的tinkerid,bugly补丁下发是按照tinkerid下发。 多个基准包使用了同一个tinkerid那说明这几个基准包都能收到你当前上传的补丁。

Q:补丁状态下发数量一直为0

A:

1.检查基准包tinkerid和补丁包.mf文件中的tinkerid

2.冷启动获取策略