在uni-app的renderjs使用fetch请求remoteurl加载超过500M文件app闪退
在uni-app的renderjs使用fetch请求remoteurl加载超过500M文件app闪退
开发环境 | 版本号 | 项目创建方式 |
---|---|---|
Windows | Windows11 24H2 | HBuilderX |
产品分类:uniapp/App
PC开发环境操作系统:Windows
手机系统:Android
手机系统版本号:Android 15
手机厂商:小米
手机机型:小米14Pro
页面类型:vue
vue版本:vue3
打包方式:云端
操作步骤:
先下载这个文件到本地
const cachePath = '_doc/project/lix_indoor.las';
const task = plus.downloader.createDownload(
'http://192.168.31.79:8080/lix_indoor.las',
{
filename: cachePath
},
(d, status) => {
// 下载完成
if (status == 200) {
console.log('Download success: ' + d.filename);
} else {
console.log('Download failed: ' + status);
}
}
);
task.start();
再把这个文件转成remoteurl
plus.io.resolveLocalFileSystemURL(
cachePath,
(entry) => {
this.fileUrl = entry.toRemoteURL();
console.log(this.fileUrl);
},
(e) => {
this.message.alert('Resolve file URL failed: ' + e.message);
}
);
在renderjs 使用fetch请求这个文件
fetch(this.fileUrl)
预期结果:
希望fetch正常返回,或者能支持分块加载,
实际结果:
请求失败,app闪退,logcat报错内存溢出
bug描述:
使用api将文件转成RemoteURL,给renderjs访问 文件大小500MB , app闪退,我的目的是需要在threejs显示这个文件,所以需要在renderjs显示本地文件,只能转成remoteurl, 如果使用file://开头的地址,无法访问,如果我是通过http请求服务器访问这个文件,app能正常执行, plus.io.FileReader也不支持readAsArrayBuffer
更多关于在uni-app的renderjs使用fetch请求remoteurl加载超过500M文件app闪退的实战教程也可以访问 https://www.itying.com/category-93-b0.html
有没有可能是内存爆了
更多关于在uni-app的renderjs使用fetch请求remoteurl加载超过500M文件app闪退的实战教程也可以访问 https://www.itying.com/category-93-b0.html
内存肯定爆了,但是这就是个bug,http返回文件,不需要一次分配这么多内存,我自己已经写了一个原生http插件,解决了这个问题,官网这个就是大文件不行
针对这个问题,主要原因是大文件加载导致内存溢出。以下是解决方案:
- 改用流式处理方式,避免一次性加载大文件:
// 使用XMLHttpRequest替代fetch,支持进度加载
const xhr = new XMLHttpRequest();
xhr.open('GET', this.fileUrl, true);
xhr.responseType = 'arraybuffer';
xhr.onprogress = (event) => {
if (event.lengthComputable) {
const percent = (event.loaded / event.total) * 100;
console.log(`加载进度: ${percent}%`);
}
};
xhr.onload = () => {
if (xhr.status === 200) {
const arrayBuffer = xhr.response;
// 处理arrayBuffer
}
};
xhr.send();
- 如果必须使用fetch,可以尝试分块加载:
const chunkSize = 10 * 1024 * 1024; // 10MB分块
let offset = 0;
async function loadInChunks() {
while (true) {
const end = offset + chunkSize - 1;
const headers = new Headers({
'Range': `bytes=${offset}-${end}`
});
const response = await fetch(this.fileUrl, { headers });
const chunk = await response.arrayBuffer();
if (chunk.byteLength === 0) break;
offset += chunk.byteLength;
// 处理当前chunk
}
}