原文地址:http://www.cocoachina.com/bbs/read.php?tid=213061
别在意那个标题中的“终极版”,那只是个噱头为了把你拉进来而已。
就好像页游广告中的MM一样,你点了一定会被骗的。
写文章是非常花时间的,尤其是写到大部分人都能看懂,且逻辑正确(不一定观点正确),言语清晰,没有错别字的程度。
写这篇文章的主要目的,是把我的思路做一个整理以备查;次要目的,则是希望我的思路对你有帮助。
简单的说,就是刷我的存在感(靠这么多人回帖)和你的优越感(靠这么傻B的文章都发上来我的方法比这好一百倍我就是不想告诉你们)。
这篇文章成文都用了6个小时,前后修改了3次,标点符号和错别字改了许多。为了更多人能看到,我也只能用点小伎俩把你拉进来了。
我不求你认同我的方法,只愿你看完后能有自己的思考。
转身就走还来得及,但不要后悔哦……
-------------------------------------------------------------------------------------------------------------
0 依赖
这里说的热更新,指的是客户端的更新。
大致的流程是,客户端在启动后访问更新api,根据更新api的反馈,下载更新资源,然后使用新的资源启动客户端,或者直接使用新资源不重启客户端。
这种方式可以跳过AppStore的审核,避免了用户频繁下载、安装、覆盖产品包。
我们一般使用这种方式快速修复产品BUG和增加新功能。
本文基于 quick-cocos2d-x zrong 修改版 。
1 前言
1.1 他山之石
在实现这个机制之前,我研究了这几篇文章:
- quick-cocos2d-x基于源码加密打包功能的更新策略 by SunLightJuly
- 看到有同学在研究在线更新,希望我能帮到你一些 by Henry
- 基于Quick-cocos2dx 2.2.3 的动态更新实现完整篇 by 西门大官人
不幸的是,这几个方案我都不能直接拿来用。因此思考再三,还是自己写了一套方案。
==重要提醒==
这篇文章很长,但我不愿意将其分成多个部分。这本来就是一件事,分开的话有种开房时洗完澡妹子却说两个小时后才能来。这中间干点啥呢?
所以,如果你不能坚持两个小时(能么?不能?),或者你的持久度不能坚持到把这篇文章看完(大概要10~30分钟吧),那还是不要往下看的比较好。
当然,你也可能坚挺了30分钟之后才发现妹子是凤姐,不要怪我这30分钟里面没开灯哦……
1.2 为什么要重复造*
上面的几个方案侧重于尽量简化用户(使用此方案的程序员)的操作,而简化带来的副作用就是会损失一些灵活性。
Roberto Ierusalimschy 在 Lua程序设计(第2版) 第15章开头说:
通常,Lua不会设置规则(policy)。相反,Lua会提供许多强有力的机制来使开发者有能力实现出最适合的规则。我认为更新模块也不应该设置规则,而是尽可能提供一些机制来满足程序员的需要。这些机制并不是我发明的,而是Lua和quick本来就提供的。让程序员自己实现自己的升级系统,一定比我这个无证野路子的方法更好.
因此,本文中讲述的并非是一套通用的机制,而是我根据上面说到的这些机制实现的一套适合自己的方法。当然你可以直接拿去用,但要记住:
- 用的好,请告诉你的朋友。
- 出了问题,请别找我。
1.3 需求的复杂性
热更新有许多的必要条件,每个产品的需求可能都不太相同。
例如,每个产品的版本号设计都不太相同,有的有大版本、小版本;有的则有主版本、次版本、编译版本。我以前的习惯,是在主版本变化的时候需要整包更新,而次版本变化代表逻辑更新,编译版本代表资源更新等等。这些需要自己来定义升级规则。
再例如,有的产品希望逐个下载升级包,有的产品希望把所有资源打包成一个升级包;有的产品直接使用文件名作为资源名在游戏中调用,而有的产品会把资源名改为指纹码(例如MD5)形式来实现升级的多版本共存和实时回滚,还有的产品甚至要求能在用户玩游戏的过程中完成自动更新。
AssetsManager 那套机制就太死板,在真实的产品中不修改很难使用。
而我也不建议使用 CCUserDefault 这种东西——在Lua的世界里,为什么要用XML做配置文件?
如果抽象出我的需求,其实只有1点:
能更新一切
这个说的有点大了,准确的说,应该是 能更新一切Lua代码与资源 。
如果你的整个游戏都是Lua写的(对于quick的项目来说应该是这样),其实也就是更新一切。
1.4 版本号设计
关于上面 需求的复杂性 中提到的版本号的问题,可以参考一下这篇文章: 语义化版本2.0.0 。
我基于语义化版本设计了一套规则在团队内部使用: 项目版本描述规则 。
在这里,我尽量详细地阐述我的思路和做法,抛砖引玉吧。