请问,在更新 app 本体以后,jsb.getSearchPaths 会发生什么变化呢?是重新将包体资源路径放到搜索路径的第一位置吗?
search path的值不会存储,每次app重启启动的时候,都会恢复成默认值。app运行过程中的改动在重启后就失效了。
多谢。
结合热更新的话,热更新完后,会在 localStorage 中设置值,这个在 app 重启后应该不会丢失吧,但是在 app 更新后会不会被覆盖呢?
localStorage只是存储值,search path是需要程序运行中根据存储的值来设置的,引擎是不会自动把存储的值设置到search path的。
我知道需要手动调用 setSearchPaths,我想只要 app 更新安装后不会覆盖 localStorage 中的值,那么就没问题了。
localStorage是把数据存放在数据库文件的。安装后是否丢失得看你把数据库文件存放到哪里了。
这个是由 Cocos 控制的吗?似乎不是。
那么正常情况下,在 android 或 iOS 上,清空应用数据才会导致这个数据丢失吧?
LocalStorage在初始化不是要求传入存放的路径吗?你看看你传入的路径是什么,如果没有传入路径的话,是存在内存中的。
什么?!你是说 cc.sys.LocalStorage 的使用还要求设置存放路径,我好像没有看到跟这个相关的说明呀。
对了,我是使用的 cocos-2d-js。
没看懂关于搜索路径那块的问题到底啥意思。
我就这么说吧,LocalStorage 里面保存的数据不会因为单纯的更新操作(管你是内部热更还是直接更apk)而丢失。除非你是先卸载了原来的版本再安装新版本,或者人工清除数据
PS:我用的也是-js
@yubifeixian 这就是我要的了,LocalStorage 不会因为更新消失。
那么接着有第二个问题,安装包更新以后,那么肯定比之前热更新的资源新,所以就得手动重新设置应用的 searchPaths 中的路径了?
按照热更新的逻辑,是要在启动时候读取 LocalStorage 中的 searchPaths 的,现在更新应用,就得重新把 searchPaths 中的 app 资源位置放到最前面。可是,热更新的 searchPath 可以在热更新成功时候设置,应用更新如何重置 searchPaths 呢?
我对于 searchPaths 有这样的认知:searchPaths 中的路径,热更新的在前面,所以热更新的资源位置优先。
额,我不明白的地方就是你说的setSearchPaths跟LocalStorage 有什么关系……
因为
1、我做热更新的时候压根没有手动设置过搜索路径;
2、我搜了一下也只搜到jsb.fileUtils.setSearchPaths(searchPaths);没觉得跟 LocalStorage 有什么关系;
也许我有什么地方理解错了,不过不重要,我最想说的是:
请忘记-js的热更新,当它不存在比较好,因为实际问题多到爆炸……
我且不说你遇到的“先热更,再手动下载apk进行更新后导致实际使用的代码还是之前热更里的代码(因为有搜索路径优先的设定)”,
就算你能保证每次都用热更新,当用户从基础包连续更新多个版本时,也会存在无法保证顺序的问题。(比如从1.0更新到1.2,需要依次更新1.1 ,1.2 ,你可以保证下载顺序的先后,但无法保证解压顺序,所以可能会出现1.2后下载但是先解压完,然后1.1再解压完,这个时候1.1会覆盖1.2中的同名文件,最终你的代码可能会出现部分文件是1.1的,部分文件是1.2的)
跟 LocalStorage 的关系是,热更新完,要把新的 searchpaths 设置到里面,以供重启后从里面加载并设置。
我的做法也是将每个版本的热更新的资源放到同一 storagePath 下。
但是,从 1.0 更新到 1.2,不是直接更新就行了吗,文档里明确提到了,不需要更新中间版本的。
而且以我对资源的理解,热更新会将脚本和其他资源覆盖更新,所以应该可以直接跨版本更新的吧。
如果你的热更新每次都把全部代码(无论本次更新有没有动到这个文件)那是可以。但我私以为,热更新的目的之一就是不想把所有代码都来一遍啊
为了避免你那个问题,把所有资源都构建用来热更新比较好,反正只是多耗费一点流量。
但是,即使不这样,只要1.1更新成功再更新1.2不就好了吗?如果更新不成功就不更新1.2。
所以现在,是否可以回到我的最初问题,在应用更新后,如何使得 searchPaths 重置?有没有办法设置一个安装钩子,在其中执行一些操作?
那应该是js绑定那层做了这些事情。@panda你知道吗?
这个问题 @yubifeixian 已经解答了
在热更新过程中,会检查应用包内的 manifest 版本和本地缓存的 manifest 版本,哪个新用哪个。那么现在问题就在于游戏启动过程中,要不要加载 search paths 了。我们的例子中,search paths 是在 main.js 最开头手动添加的,但是对于已经更新过的游戏可能就会有问题,解决方案有几个:
- 不同的版本记录不同的 search paths,比如 version 1.0 在 local storage 中对应的 search paths 是 “hotUpdatePaths_v1.0”,version 1.1 对应 “hotUpdatePaths_v1.1”,可以做清除之前版本 search paths 的逻辑
- 用同样的 search paths key,在新更新的版本 main.js 中做这样一件事情:
var hotUpdatePaths = JSON.parse( cc.sys.localStorage.getItem("hotUpdatePaths") );
// 第一个其实就是 storagePath
var manifestUrl = hotUpdatePaths[0] + "res/manifests/project.manifest";
var manifestStr = jsb.fileUtils.getStringFromFile(manifestUrl);
if (manifestStr) {
var manifest = JSON.parse(manifestStr);
// 当前更新的 app 版本是 1.1,只有当缓存的版本比 1.1 更高时,才使用这个 search paths
if (parseFloat(manifest.version) > 1.1) {
var paths = jsb.fileUtils.getSearchPaths();
// local storage 中存储的 paths 必须放在默认的 paths 之前
paths = hotUpdatePaths.concat(paths);
jsb.fileUtils.setSearchPaths(paths);
}
}
默认的热更新逻辑并不是传统的差分包更新(按顺序下载多个中间版本的差分包),而是动态计算当前本地版本和远程版本的差异,生成动态的更新列表来进行更新。所以热更新过程中,文件下载顺序不保障,因为不会遇到互相覆盖的问题,也不会要求更新所有资源(没有修改的文件不会进入动态的更新列表)。
不同的版本记录不同的 search paths,比如 version 1.0 在 local storage 中对应的 search paths 是 “hotUpdatePaths_v1.0”,version 1.1 对应 “hotUpdatePaths_v1.1”,可以做清除之前版本 search paths 的逻辑
就这个办法而言,如何在更新 app 之后,清除前一次 path 呢?
第二个办法确实可以。
第一个办法你可以在新版本中记录一下之前的版本列表来清除,虽然比较笨,但是可靠
我之前理解错了,原来是在 localStorage 中将不同版本作为键名。
那么应用更新后,在 main.js 里面写死一个版本键名,并加上判断,如果本地存的那个版本旧就不用那个,然后以后热更新存入更新的键名。
多谢。我想这两个办法就够了。出发点都是一样的,将一些信息写到更新包里,并且不受 searchPaths 影响。