[LayaAirIDE 2.0]关于laya无法缓存非图片、声音文件bug

版本:LayaAirIDE2.5.0
-------------------------
采坑过程:
由于需要缓存非图片、声音文件(laya默认只缓存这两种文件),
根据官方介绍修改了 Laya.MiniAdpter.AutoCacheDownFile = true;
详见 https://ldc2.layabox.com/doc/?nav=zh-ts-5-0-5​ 
 
在微信开发工具测试一切正常,
然后放到真机测试发现无法缓存了,在网上也找了各种资料没发现有比较好的解决方案
大部分都是说放弃laya自带的缓存方案,使用第三方提供的,具体就不在这里说明了,有需要自己网上找一下
-------------------------
因为使用其他方案会有一些局限性,而且随着laya版本的更新可能也会有不兼容的情况
所以就开始研究laya的缓存源码,最后发现是以下原因导致,详见(图一)readFile
QQ图片20200529162837.png

添加红框中代码后真机测试可以正常缓存文件了,但是另一个问题来了
当第二次重启小游戏的时候,需要重新加载缓存,也就是需要重新 readFile 
就会重新触发 copyFile 函数,相当于复制自身
而微信的 copyFile 复制自身的话真机环境下好像会清空自身文件内容(我真机实测是这样,开发工具正常,具体原因不明)
所以第三次重启小游戏后,由于缓存的文件在第二次被清空了(文件还在,但是数据是空的)
也不会去下载cdn的文件了,导致报错;所以在 copyFile 加了以下红框中内容,详见(图二)
QQ图片2.png

真机测试后正常
------------------------
以上是个人的修改方案,可能有缺陷,希望官方大大能给下建议,看是否有更好的解决办法?
 
问题扩展: @官方 以下两个Obj区别是什么?有点不太明白用意,
    MiniFileMgr.filesListObj = {};
    MiniFileMgr.fakeObj = {};
 
        static copyFile(tempFilePath, readyUrl, callBack, encoding = "", isAutoClear = true) {
            var temp = tempFilePath.split("/");
            var tempFileName = temp[temp.length - 1];
            var fileurlkey = readyUrl;
            var fileObj = MiniFileMgr.getFileInfo(readyUrl);
            var saveFilePath = MiniFileMgr.getFileNativePath(tempFileName);
            MiniFileMgr.fakeObj[fileurlkey] = { md5: tempFileName, readyUrl: readyUrl, size: 0, times: Laya.Browser.now(), encoding: encoding };
 
 
而且这行代码 MiniFileMgr.fakeObj[fileurlkey] = { md5: tempFileNamereadyUrl: readyUrlsize: 0times: Laya.Browser.now(), encoding: encoding };
会导致插入一些 size为0的空数据,但实际该文件不存在本地缓存中
getFileInfo 使用的就是该obj存储的数据,不知道是否会有其他隐藏问题存在?
        static getFileInfo(fileUrl) {
            var fileNativePath = fileUrl;
            var fileObj = MiniFileMgr.fakeObj[fileNativePath];
            if (fileObj == null)
                return null;
            else
                return fileObj;
            return null;
        }
 
已邀请:

陆仁毅

赞同来自: 176*****020

readfile处进行本地文件检测是正确的的。文件列表维护确实存在问题,我们可能会在下个版本修复

176*****020

赞同来自:

大佬 请问一下缓存的音频文件真机上可以播放吗 我的调试器可以播放 但是在真机 只有在第一次从服务器下载后可以播放 第二次就没声音了

Laya_XS

赞同来自:

提供下你用引擎版本的demo的case,我们确认下这个问题,是问题的话下个版本修复。

小江村儿的文杰

赞同来自:

补充  onMkdirCallBack 方法的定义:
 
 

static onMkdirCallBack(errorCode, data) {
if (!errorCode) {
MiniFileMgr.filesListObj = JSON.parse(data.data);
MiniFileMgr.fakeObj = MiniFileMgr.filesListObj || {};
}
else {
MiniFileMgr.fakeObj = MiniFileMgr.filesListObj = {};
}
MiniFileMgr.fs.readdir({
dirPath: MiniFileMgr.fileNativeDir,
success: function (data) {
var tempMd5ListObj = {};
var fileObj;
for (let key in MiniFileMgr.filesListObj) {
if (key != "fileUsedSize") {
fileObj = MiniFileMgr.filesListObj[key];
tempMd5ListObj[fileObj.md5] = true;
}
}
var files = data.files;
var fileName;
for (let i = 0, sz = files.length; i < sz; i++) {
fileName = files;
if (fileName == MiniFileMgr.fileListName)
continue;
var deleteFileUrl = MiniFileMgr.getFileNativePath(fileName);
if (tempMd5ListObj[deleteFileUrl]){
delete tempMd5ListObj[deleteFileUrl];
continue;
}
if (tempMd5ListObj[fileName]){
delete tempMd5ListObj[fileName];
continue;
}
MiniFileMgr.fs.unlink({
filePath: deleteFileUrl,
success: function (data) {
console.log("删除无引用的磁盘文件:" + fileName);
}
});
}
for(var each in tempMd5ListObj){ // 【这里是重点】
for(var key in MiniFileMgr.filesListObj){
if (MiniFileMgr.filesListObj[key].md5 == each){
delete MiniFileMgr.filesListObj[key];
console.log("删除无本地文件的记录:", key, each);
break;
}
}
}
}
});
}

要回复问题请先

商务合作
商务合作