为什么我在 Android 上的 appcelerator mobile 中下载多个文件时内存不足

发布于 2024-12-21 22:02:48 字数 2507 浏览 1 评论 0原文

我也在 appcelerator 论坛上问过这个问题,但我发现我经常从 stackoverflow 上可爱的人们那里得到更好的答案,我也在这里问这个问题,以防有人可以传播一些信息。

我创建了一个 url 的 downloadQueue 并使用它通过 httpclient 下载文件。 downloadQueue 中的每个文件一次发送一个到 httpclient,只有在前一个下载完成后才会启动下一个下载。 当我开始下载时,它似乎工作正常,并设法下载了几个文件,然后它就冻结了,并且我在 DDMS 错误日志中收到“内存不足”错误。 我尝试实施在其他帖子中找到的建议,其中一个示例是:

[http://developer.appcelerator.com/question/28911/httpclient-leaks-easily-or-can-we-have-a-close-method#answer -104241][1]

[http://developer.appcelerator.com/question/35041/large-file-download-on-mobile][2]

[http://developer.appcelerator.com/question/120129/httpclient-and-setfile][3]

[http://developer.appcelerator.com/question/95521/httpclient---save-response-directly-to -file][4]

我尝试了以下所有操作: - 直接从本机路径移动较大的文件下载,而不是简单地保存到文件,以确保 tmp 文件的保留时间不会超过必要的时间。 使用 httpclient 的 undocument setFile 方法。 (这让我的代码死了,没有任何错误消息,而且由于它没有记录,我不知道它是否曾经在android上实现过)

- 在文件下载后使用httplient.onload中的settimeout在请求之前暂停1秒下一个文件(我不知道这会有什么帮助,但我现在抓住了一根稻草)

下面是我的代码的相关部分(除了 GetFileUrls 函数之外,它是完整的,为了简单起见,我排除了该函数,因为该函数所做的所有事情都是返回一个URL 数组)。

谁能发现任何可能导致我的记忆问题的东西。当我尝试了我能想到的一切时,有人有任何想法吗? (帮助!)

var count = 0;
var downloadQueue = [];
var rootDir = Ti.Filesystem.getExternalStorageDirectory();

downloadQueue = GetFileUrls(); /* this function is not included in order to keep my post as short as possible, bu it returns an array of urls */
DownloadFile(downloadQueue[count]);

var downloader = Ti.Network.createHTTPClient({timeout:10000});

downloader.onerror = function(){
    Ti.API.info(this.responseData);
}

downloader.onload = function(){
    SaveFile(this.folderName, this.fileName, this.responseData);
    count += 1;

    setTimeout( function(){ DownloadFile(); }, 1000);
}

function DownloadFile(){
    if (count < downloadQueue.length){
        var fileUrl = downloadQueue[count];
        var fileName = fileUrl.substring(fileUrl.lastIndexOf('/') + 1);

        downloader.fileName = fileName;
        downloader.folderName = rootDir;

        downloader.open('GET', fileUrl);
        downloader.send();
    }
}

function SaveFile(foldername, filename, response){  
    if (response.type == 1){
        var f = Ti.Filesystem.getFile(response.nativePath);
        var dest = Ti.Filesystem.getFile(foldername, filename);

        if (dest.exists()){
            dest.deleteFile();
        }

        f.move(dest.nativePath);
    }else{
        var dest = Ti.Filesystem.getFile(foldername, filename);
        dest.write(response);
    }
}

I have asked this question also on the appcelerator forum, but as I find I often get better answers from you lovely people here on stackoverflow I am also asking it here just incase anyone can spread some light.

I have created a downloadQueue of urls and am using it to download files with the httpclient. Each file in the downloadQueue is is sent the the httpclient one at a time, with the next download being initiated only after the previous has been completed.
When I start the download, it seems to be working correctly and manages to download several files before it it simply freezes and I get an "out of memory" error in the DDMS error log.
I tried implementing suggestions found in other posts a sample of which are:

[http://developer.appcelerator.com/question/28911/httpclient-leaks-easily-or-can-we-have-a-close-method#answer-104241][1]

[http://developer.appcelerator.com/question/35041/large-file-download-on-mobile][2]

[http://developer.appcelerator.com/question/120129/httpclient-and-setfile][3]

[http://developer.appcelerator.com/question/95521/httpclient---save-response-directly-to-file][4]

I tried all of the following:
- moving larger file downloads directly form the nativepath rather then simply saving to file in order to insure that tmp files are not kept longer then necessary.
using the undocument setFile method of the httpclient. (This stopped my code dead without any error message, and as it is undocumented I have no idea if it was ever implemented on android anyway)

-using a settimeout in httplient.onload after the file has been download to pause for 1 second before requesting the next file (I have no idea how this would help, but I am clutching a straws now)

Below is the relevant parts of my code (which is complete except for the GetFileUrls functions which I excluded for simplicity sake as all this function does is return an array of URLs).

Can anyone spot anything that might be causing my memory issue. Does anyone have any ideas as I have tried everthing I can think of? (HELP!)

var count = 0;
var downloadQueue = [];
var rootDir = Ti.Filesystem.getExternalStorageDirectory();

downloadQueue = GetFileUrls(); /* this function is not included in order to keep my post as short as possible, bu it returns an array of urls */
DownloadFile(downloadQueue[count]);

var downloader = Ti.Network.createHTTPClient({timeout:10000});

downloader.onerror = function(){
    Ti.API.info(this.responseData);
}

downloader.onload = function(){
    SaveFile(this.folderName, this.fileName, this.responseData);
    count += 1;

    setTimeout( function(){ DownloadFile(); }, 1000);
}

function DownloadFile(){
    if (count < downloadQueue.length){
        var fileUrl = downloadQueue[count];
        var fileName = fileUrl.substring(fileUrl.lastIndexOf('/') + 1);

        downloader.fileName = fileName;
        downloader.folderName = rootDir;

        downloader.open('GET', fileUrl);
        downloader.send();
    }
}

function SaveFile(foldername, filename, response){  
    if (response.type == 1){
        var f = Ti.Filesystem.getFile(response.nativePath);
        var dest = Ti.Filesystem.getFile(foldername, filename);

        if (dest.exists()){
            dest.deleteFile();
        }

        f.move(dest.nativePath);
    }else{
        var dest = Ti.Filesystem.getFile(foldername, filename);
        dest.write(response);
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

和我恋爱吧 2024-12-28 22:02:48

尝试使用事件而不是您正在使用的嵌套递归。 Android好像不太喜欢这个

try to use events instead of the nested recursion that you are using. Android does not seem to like that too much

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文