• 做一个幸福的人,读书,旅行,努力工作,关心身体和心情。
  • 不管有没有人爱,也要努力做一个可爱的人。不埋怨谁,不嘲笑谁,也不羡慕谁,阳光下灿烂,风雨中奔跑,做自己的梦,走自己的路。

程序的增量更新

Qt lcq 3年前 (2015-06-12) 688次浏览 0个评论

增量更新在各种软件上已经随处可见了。比如现在的一些安卓应用的分发平台,大部分都是采用的增量更新。因为现在的软件越做越大,采用全量更新不仅会浪费网络资源,而且给用户带来很不好的体验。

以前我做一个的一个工具本来是要对数据进行增量更新的。那时候下载下来的一个应用最大的700多兆。这700多兆程序文件占用不超过2M,其他的都是数据。当然,这700多兆接过我们使用压缩工具压缩之后是只有300多兆左右的,可这300多兆对于用户来说更新体验还是非常糟糕的。当然,你不要跟我说下载速度10M/s,半分钟就下载下来了。你永远不要想所有的用户都有这么好的网络资源。加之我们购买的CDN服务可能比较差,我远程过一些用户,售点,他们更新的速度基本都是以Kb/s计算的(差的网速可能就是十多Kb/s)。能看到一个速度稳定在200Kb/s的就很不错了。所以,增量更新就成了当时的一个比较重要的需求。但是遗憾的是我代码实现到一半多的时候,公司把我调到其他地方做安卓开发去了。幸好当时有笔记,所以还是讲当时做的笔记放上来吧,供以后参考。

套装更新

序号

更新方法

优点

缺点

1

对比小机与网络上的upd版本,如果小机的upd版本比网络的upd版本低,则将整个套装下载下来更新整个套装。

更新方法简单,不易出错。

更新时间长,有些不需要更新的文件也会更新一遍。

2

跟方法1类似,只是在后台先将所有的套装先下载下来,当用户更新的时候,直接执行复制过程。

不管是用户下载新的套装或者用户更新套装,都省去了用户去下载的过程。

会对用户的网络造成一定的影响,如果没有在后台将需要更新的文件提前下载下来,用户也需要执行下载过程。

3

做增量更新包。将所有版本的套装的差异找出来,将这些有差异的文件打成一个包,再根据小机套装的版本号与网上版本号进行比较,下载对应的更新包。

更新速度快,更新准确。

随着版本的增加,增量包的数目会成爆炸式的增长,后期维护困难。

4

每个套装里面的每个文件都有一个版本号,根据小机的文件列表与网络套装的文件列表以及每个文件的版本号,进行更新。

后期维护简单。

所有的文件都必须要有个版本号。如果更新的文件过多,反复下载反复解压的过程中工具出错概率比较大。

我当时做的是第4中方法。一旦做成,因为后期更新很多的时候都只是一个程序文件更新,这对用户的更新体验有着极大的提升。当时连后台数据都做好接口了的。当时很想做可惜没有做成,反正做与不做都是领导一句话吧。

在这里我想要说的是Qt应用程序的增量更新。写过Qt的人都知道,随便你做个有界面的最简单的显示Hello World的Qt应用程序,Qt的一些核心dll至少要五十多兆。用压缩软件压缩之后还是有十多兆。如果你要用些什么插件之类的,就算压缩之后超过五六十兆是分分钟的事情。不像MFC是Windows系统的亲儿子,需要的dll基本系统都自带了,所以打包之后也就几兆的样子。这时候全量更新跟增量更新就没什么分别了。但由于Qt自带的dll很大,如果你不改Qt的版本,这些dll是不需要更新的。所以用Qt写的应用程序使用增量更新从用户的体验角度来说,就很重要了。实现主要是我以前的一个同事写的代码,所以我也是阅读他以前的源码,然后自己写了一个小小的demo,将思路整理一下(其实就是上面的第4种思路吧),供有需要的人参考一下。

程序的大概思路如下图所示:

思路其实很简单。说一说其中的一些实现小细节或者说小技巧吧。

1、如何检测主程序是否需要升级。你在你的程序里面写一个版本号,然后获取网上的一个最新的版本号。通过比较即可。当时网上的Json数据的一个实例如下:

解析一下上面的几个关键字,其中version是网上的最新版本。url是这个最新版本全量包的下载地址。需不需要更新,你用本地的version跟网上的version比较即可。顺带解析一下这段Json字符串的含义。fileDifference主要是用来查找低版本升级到网上的最新版本所需要下载的更新包。比如本地为0.99的版本,它应该下载名字为2048PatchV0.99_V1.00.exe的增量包,而本地为0.01的版本则需要下载2048PatchV0.01_V1.00.exe的增量包。

2、制作增量包的一个小技巧。假设我们已经发布出去了N个版本,我们即将要释放第N+1个版本。假设从版本1—>N+1其中a.dll有改变,版本2–>N+1有b.dll改变。版本3–>N+1有c.dll改变。版本4–>N+1依然是a.dll改变。。。总之,版本1到N升级到版本N+1都是其中的a.dll,b.dll,c.dll有改变。本来我们对于版本1的增量包只含有a.dll,版本2的增量包只有b.dll,依此类推。但是这样我们做的增量包会非常复杂。这个时候,你就可以将所有从版本1到版本N升级到N+1的变化的东西都放在一起做成一个增量包,这样,你就不要做很多的增量包了。放心,这些“大”的增量包没有你想象中的大的。一般程序也就2兆左右,完全可以接受。当然,根据上面理论,如果要发布第N+1个版本,我们必须要做N个增量包。但是一个很旧的版本的版本更新的最新版本可能增量包会非常大,这个时候,你就让他全量更新吧。增量更新你只要保证最近的5个版本基本就差不多了(当然,如果你的公司一个星期发布一个版本,那另当别说了。)

3、Qt如何启动其他应用程序。请查看Qt的QProcess类。使用startDetached函数即可。后面的QStringList参数是如果你启动的程序的main函数的char *argv[]会接收到。

4、增量包如何安装。当然有各种各样的方法。比如你可以把这个增量包包含的文件使用一个压缩软件打成一个包下载下来,然后使用更新程序将它解压,然后将文件复制到所需要的目录。但是可能有点小问题的是:如果你的更新程序启动需要依赖某个dll文件,而这个被依赖的dll文件恰好也需要更新,这时候你是无法进行覆盖原来的旧文件的。所以当时当时用了一个比较讨巧的方法,就是将增量包使用打包工具NSIS(可以参考我的另外一篇博文Qt程序打包发布)打成一个安装包。然后更新程序启动那个增量更新的安装包之后马上自动退出程序。这样那个增量更新安装包就可以正常释放更新文件了。

5、如果更新程序也需要更新如何处理?很简单。把更新程序打包到那个增量更新包里面。

6、更新包如何将文件正确释放到安装程序的目录。可以这样做:每次主程序启动,都将自身所运行的路径写入到注册表里面去。然后再检测是否需要更新。增量包安装的时候,去读取这个注册表,然后将文件释放到这个目录下面去。这样无论用户将主程序的运行的目录换到哪里(因为有些“绿色”软件用户可能拷来拷去嘛),更新程序都能准确的找到主程序的运行目录。如果你需要了解更新包如何获取注册表的信息,那你需要学习一下NSIS的脚本制作了。

7、增量包正确安装之后如何启动主程序。还是要看NSIS脚本制作。。。。。

好吧,感觉差不多了。以后有什么问题再来补充一下。我测试用的小demo已经上传到github了。代码也不是很复杂。大家看完上面的,再看看代码应该很快就能明白了。主程序地址:https://github.com/luchenqun/Qt2048。增量更新程序地址:https://github.com/luchenqun/DownloadToolUpdate。


参考资料:

1、软件的升级、更新是个怎样的过程

2、浅析android应用增量升级

3、空哥(DownloadToolUpdate代码贡献者)


乐趣公园 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明程序的增量更新
喜欢 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址