前言:
小生不才,斗胆写一篇热更新的文章.
为什么项目中要用到热更新:
a:刚进入一家公司,前任android代码烂的没办法下手,单元测试没有写,网络框架没有封装,甚至基类都没有.
b:对于职场小白或者中途进入公司做项目的人,一般都不会再去写单元测试浪费时间,就导致我们可能马虎一点就出现了Null outputInfo ... 各种简单解决影响app运行的问题
以上种种原因吧,当然都是我一点点深有体会的坑,这时候就用到热修复啦,虽然不能完全解决你的问题,但是可以把你的问题影响缩小到最小化,不能让用户再次去更新,让运营再次去上传,测试在次去测试,产品再次去验收啦.很nice. 很Punchline skr skr....
热更新对比图片
还有一个TinkerPatch平台 个人认为他就是Tinker的封装优化版本,也欢迎大家去研究,他的接入我认为应该说是最简单的
文档 - Tinker Platform - Android 热补丁平台
为什么我选择Tinker
其实原因很简单,因为他支持的东西最多,而且对多渠道,加固签名都已经很支持啦,而且我们统计用的Bugly 所以懒惰(帅气)的我毫不犹豫的选择了Tinker,当然有兴趣的大神可以去接入一下其他的热修复,各有利弊嘛! 哦对 大神也不会来看我的帖子 打扰了.
第一步接入sdk
请大家看文档接入,
注意!!!!:
如果之前接入过bugly的bug统计的请去除重复引用的 implementation 'com.tencent.bugly:crashreport:latest.release ' 这个地址,不然回报又重复jar包的错误(没有就忽略,按照文档操作来就OK)
tinker-support.gradle这文件里面baseApkDir只不过是一个格式,并不是写死的地址.tinkerId 是必填的,因为到时候热修复的时候,补丁包是通过tinkerid来匹配你要修补的那个包.最好是根据版本号来定义(基础包|补丁包):: tinkerId ="2.3.4-base" | tinkerId ="2.3.4-patch" 前者是基础包 后面是补丁包,这样有一些区分 不至于后面乱了.
tinkerPatch里面的东西一般情况下不需要动,文档里面也有介绍
文档里面的第三步:enableProxyApplication = false 或者true的情况.我是直接搞为true,false太麻烦了
第五步混淆文件的话,如果之前一直没有混淆的话,也不建议这次混淆,因为你项目太大的话,sdk肯定很大,直接一直没有混淆,这次混淆的话 需要去把所有的混淆文件找出来 一个个的很麻烦.
命令或者Gradle打包
命令打包: gradle assembleRelease,个人建议 信用命令去打包一下,如果打包过程中出现错误 直接可以gradle assembleRelease --staktrace 来直接查看错误
举例:
然后我们通过 gradle assembleRelease --staktrace 来进行排查错误
进一步去看根目录下的gradle.properties
把他设置为false就OK啦.然后我再次执行命令打包可以看到 之后输出的是 BUILD SUCCESSFUL.成功啦.如果中途遇到问题 用此方式去搞定.或者留言给我也可以.随后我们清楚一下clean assembleRelease 一下,然后没啥问题就可以按照文档去打包了
打完包应该可以到如下图的路径配置
有的人说为什么我的里面只有apk跟R.txt文件 没有mapping.txt文件.是因为没有混淆,所以mapping文件不会产生,但是并不会影响你的接入的任何问题,也建议大家 multiDexEnabled release 的时候 设置为true,当然项目大我就不太建议了.有时间改最好.
如果打完包之后如上面图片目录大同小异的话,基础打包就已经OK啦.这个包是可以上传应用市场的包,如果上线之后发现此包有问题了,接下来咱们就开始使用补丁包啦
先去把线上所发现的问题修改完毕,之后我们需要重新配置一下tinker-support.gradle这个文件图片操作一遍把,我认为这样会更清楚
把 ${baseApkDir} 换成了下面图片 bakApk下面apk的文件路径 必须要一模一样,因为这边就是你需要补丁包替换的东西,不然会生成补丁包出错,至于tinkerId 可以改也可以不改,我建议改i 下 因为这样明确一点,不至于以后项目更大之后你不知道是打的补丁包还是基础包了.
如果不出问题的话 按照文档操作来的话 应该可以看到app-build-outputs-有三个apk,把那个zip的apk按照文档上传到bugly-选择应用-应用升级-热更新-发布新补丁啦.基本完成.需要重启,对比图上看也说过了.不支持即时生效.
如果您已经安装了基础包了,并确保thinkid没问题的话,还依然出现下面这种问题,说明直接初始化了2次,比如你之前接入过了bugly的bug统计初始化了,然后接入热更新的时候还按照热更新的文档初始化了 可能会出现这种问题,按照热更新的文档初始化来就OK,本人测试过了,依然还可以bug统计,不会影响bugly统计的任何问题,或者也可能是你没有配置release 的keystore他拿的你程序默认的keystrore 也会出现这种问题,需要自行配置一下release 的keystore.在build.gradle里面,百度去吧 兄弟 可能你去学到更多的东西
基本操作完结
完结之后比如基础包在线上突然出现了问题,就可以把补丁包上传到bugly上面更新啦.自己里面也有一些配置,如下图,自己可以配置了,本人建议在发布了这个版本可以提示他自动重启,然后给他在loading界面下载补丁,ok进入app,不ok的统计问题上报一下,然后再让他进入app,我认为只有线上产品出现多次崩溃的时候才会启用热更新,所以崩溃了肯定是退出app,所以在此重启的时候做一下处理就好.有问题留言联系我哦.
多渠道打包
难道你还在用build文件配置里面来打包生成嘛,个人认为太慢了, 借助友盟 乐固等一些软件来打包嘛 太慢了 太慢了 太慢了.
我们分析一下,渠道就是apk的一个标识而已,我们接入的是TaklingDate 跟 umeng ,他们在初始化的时候都可以init过去渠道.所以我们就可以想办法搞一个apk中的维一标识出去,而且每个apk的标识都不一样,这样这个标识就是我们的渠道,我在网上看到美团等打包,我们可以通过python来搞.简单的说就是每个apk其实就是一个zip压缩文件,然后我们可以在apk里买用python大进入一个文件,文件的名字就是我们的渠道,这样我们就可以通过获取缓存文件获取到这个文件,然后获取到名字,这个名字就是我们的渠道啦.不过好像听着很麻烦 别担心 这么简单的办法 百度里的大神肯定有封装啦.
GitHub - wangtao2855/PythonChannelApk: python写的多渠道打包
大家可以看一眼这博客,有问题咨询我,或评论.真的很快 1秒百包,比泰迪都快(听不懂的说明还是年轻啊).
我们可以先把热更新一个包弄好,不需要考虑多渠道打包,到时候用python的方式搞一下多渠道就好.跟热更新一分钱关系都没有. 节省我们去搞热更新多渠道打包的麻烦.是不是很爽,在马桶上的你赶紧搞起来.搞起来
加固apk
其实我感觉他还是太坑了,虽然支持加固再次签名等问题,但是依然还是太坑
我试过了如果不把这个参数设置为true.加固后的包虽然能下载补丁文件,但是没什么乱用,补不进去.所以如果要加固的包必须把此属性设置为true.顺便说明一点.如果你设置为true.你打出来不是加固包,他依然不能使用补丁包.结果就是说需要加固的把他设置为true.不需要的设置为false.因为我本人没太了解过Groovy语言,需要懂得大佬帮忙我封装一下,不用多次因为一个属性重复编译了. 哦忘记了 大佬不会看我的文章 打脸了 扎心了.
以上内容就大概这些东西把.其他的有问题,请跟我沟通哈,反正我遇到了很多坑,也不知道是我想的多还是我倒霉,(肯定不是我技术差),
最后 送我我demo供大家欣赏
(ps:因本人太懒了,所以demo中很多没用的地方,隐藏的地方尽量不要看 也没啥帮助,大家凑合凑合把,说不定你还没搞完这个功能-你就转行了呢,或者说你搞着搞着就猝死了呢,或者说你搞完了就被解雇了-你就跳楼了呢,哈哈哈哈)
demo中animationdemo--build--bakApk--...0831-17-43..--....apk是基包的apk,
animationdemo--build--outputs--patch--release--patch_signed_7zip.apk是补丁包放到bugly中
GitHub - wangtao2855/TinkerEasyDemo: 一个基于Tinker的demo.亲测,可以正常运行起来