Similar memory leak problem like in:
http://developer.appcelerator.com/question/81381/httpclient-memory-leak
http://developer.appcelerator.com/question/28911/httpclient-leaks-easily-or-can-we-have-a-close-method
My mobile application downloads large PDF files and shows them to the user. However, HTTPClient causes memory leaks.
Could it be possible to use the new FileStream with the HTTPClient to read and write 1k chunks to avoid memory problems?
http://developer.appcelerator.com/blog/2011/05/titanium-mobile-intro-series-streams.html
EDIT: Solved! Using BlobStream did the trick since responseData is a TiBlob object.
3 Answers
Accepted Answer
couple of things:
when you use the "onload" event, you already have the entire date, so why not use Titanium.Filesystem.getFile and .write method to write the content to the file?
Second, when using large data (and downloading in general), use the (undocumented) method setFile:
var c = Titanium.Network.createHTTPClient({timeout:10000}); var filename = 'test.pdf'; var f = Titanium.Filesystem.getFile(Titanium.Filesystem.externalStorageDirectory, filename); // I use applicationDataDirectory on iOS instead if (!f.exists()) { try { c.onload = function(){ showPDF(f); }; c.ondatastream = function(e){ }; c.onerror = function(e){ Ti.API.info('XHR Error ' + e.error); }; var downloaduri = 'http://www.domain.com/test.pdf'; // open the client c.open('GET', downloaduri); c.setFile(Titanium.Filesystem.externalStorageDirectory + "/" + filename); // send the data c.send(); } catch (e) { Ti.API.info("Error", Titanium.API.error); } }setFile should appear before send and after the open method. It will save the contents of the call to the file path you specified, without it saving the responseData in the object, leading to a HUGE memory save.
OK, a simple example:
var c = Titanium.Network.createHTTPClient({timeout:10000}); var filename = 'test.pdf'; var f = Titanium.Filesystem.getFile(Titanium.Filesystem.externalStorageDirectory, filename); // I use applicationDataDirectory on iOS instead if (!f.exists()) { try { c.onload = function(){ if (c.readyState == 4) { var instream = Titanium.Stream.createStream({ mode: Titanium.Stream.MODE_READ, source: this.responseData }); var outstream = f.open(Titanium.Filesystem.MODE_WRITE); // Create a buffer for chunking the data. var buffer = Ti.createBuffer({length: 1024}); // Read and write chunks. var read_bytes = 0; while ((read_bytes = instream.read(buffer)) > 0) { outstream.write(buffer, 0, read_bytes); } // Cleanup. instream.close(); outstream.close(); showPDF(f); } }; c.ondatastream = function(e){ }; c.onerror = function(e){ Ti.API.info('XHR Error ' + e.error); }; var downloaduri = 'http://www.domain.com/test.pdf'; // open the client c.open('GET', downloaduri); // send the data c.send(); } catch (e) { Ti.API.info("Error", Titanium.API.error); } }
Could you give us a code example how you work with HTTPClient and BlobStream?
Your Answer
Think you can help? Login to answer this question!