热更新hot update大纲

对于热更的重要性,相信大家都了解。做游戏行业近3年了,在更新过程中涉及到方方面面的问题。在次对热更新做一下梳理,希望同学们不要在相同的坑上跌倒。

1、首先说下什么是热更新(what)

经常有人说静态语言无法热更,动态语言可以热更,那么什么是静态语言,什么是动态语言?简单的说:
  • 强类型语言(静态类型语言)是指需要进行变量/对象类型声明的语言 一般情况下需要编译执行。
  • 弱类型语言(动态类型语言)是指不需要进行变量/对象类型声明的语言,一般情况下不需要编译(但也有编译型的)。

脚本语言毫无疑问是动态类型语言,对于他们能否热更毫无疑问,那么c, c++, oc, java 这些语言能否热更?答案是:能。C/C++也可以热更新,例如在Windows上是可利用LoadLibrary()和FreeLibrary()实现。现实例子是Unreal引擎4用这种方式使用C++做「脚本」。

java本身是运行在虚拟机上,而c++可以使用动态链接库,这些都是语言上的动态性。所以所谓的静态语言无法热更不是真的无法热更,而是成本太高,不适合热更罢了。

PS:就IOS而言,iOS Developer Program License Agreement里3.3.2提到不可动态下发可执行代码,但通过苹果JavaScriptCore.framework或WebKit执行的代码除外。另有说法称ios使用cpu的No eXecute bit:大致就是将appstore审核过的代码加入签名文件,然后ios运行app的时候会为appstore审核过的代码开辟专用的内存空间,而其他app中的数据或者通过代码从线上下载的数据加载的时候会将存放的内存空间定义描述符定义为禁止运行,这样ip寄存器将不能够跳转到该空间,因此这部分代码不能运行。而为什么lua等脚本语言可以热更,因为lua在不开启JIT的情况下是解释运行,也就是通过软件cpu来执行这些代码,而模拟器代码在提交的时候已经通过了appstore之类的审核是可以被cpu执行的,你热更的lua脚本只是一种数据,被模拟器加载了而已,因此不会被No eXecute bit技术所限制。

简单理解,lua运行在虚拟机上的,虚拟机本身被打上了签名,而lua脚本作为数据,并不会被阻止。

所以,确切的说能否热更,取决于代码所属部分是否是语言是否具有动态属性并在动态链接的区域内。

2、那么何时进行热更(when)

业内的普遍做法是放置在app或者游戏启动的时候进行热更。不过热更可以在任何时候进行,甚至玩家都不会感觉到热更的存在。也就是边玩边下。

3、如何进行热更(how)

现有模式大多通过版本管理的方式进行热更。
cocos2dx 提供了2中热更新的方法AssetsManager 和 AssetsManagerEx。

先说AssetsManager,采用的是升级包的管理方法,首先进行版本号对比,然后根据url获取对应的升级包,解压升级包,设置资源加载路径,通过加载writepath目录下最新文件的方式来实现更新。逻辑清晰,简洁。

但是当涉及到跳版本更新,例如1.0升级1.2的时候,要么提供1.0-1.1,1.1-1.2,1.0-1.2多个升级包,升级一次,要么一个版本一个版本的升级。

或者在url下保存一个最高版本的升级包,即1.0-1.2升级包,这样不论用户版本是多少,都可以下载升级到最新的版本,不过试想下,如果只是一个文件的改动,用户就要下载以前全部的升级内容,升级包也会越来越大。

在说AssetsManagerEx,是之前的加强版,不同的是不在使用升级包的方式,而是采用单个文件拉取的方法。首先获取本地更新配置(记录当前版本更新了哪些文件,以及这些文件的md5),之后与服务器的更新配置做比较,得出差异文件,之后单个拉取差异文件。并且当本地版本大于服务器版本的时候,会清理掉本地更新缓存。

AssetsManagerEx也有尚未解决的问题,例如多个更新序列无法并行例如逻辑更新,显示更新,活动更新每个都会走自己的版本号与版本管理,这时候同时启动3个AssetsManagerEx是不行的,只能顺序启动。

另外版本后期随着项目的庞大配置文件几乎包含了所有的文件信息,对比文件的耗时会越来越长。

值得注意的是,热更不是万能的,有些东西无法热更,有些东西无法热更,有些东西无法热更(重要的事情说3遍)。
热更无法更新热更自己(除非重启当前进程)
1、热更自身的代码
2、热更界面的资源
3、热更过程中出现的提示弹窗
4、脚本启动代码main.lua

你可能感兴趣的:(cocosdx-3.4)