Search code examples
titaniumtitanium-mobile

Titanium Preloading Images


I am wondering how Titanium handles images. If I were to load an image in a image view, then change the image in the image view to a local image, and then change the image back to the previous image would the image view need to download the previous image again?

Not sure how Titanium handles downloaded images, but I would think it does not cache them.

I was thinking i could create some off screen images and set some other Image Views to their image url, but would this work? Or would the image view download the image?

Just trying to figure out how the image views work in titanium and the best way to ensure I can preload/reuse images.

Thanks


Solution

  • Update April 2015: As of Titanium 3.X, there is caching in images as per Gautier's answer below


    There is no caching of remote images in an ImageView by default. In your scenario, the remote image would be redownloaded again when you switched back to it.

    In most of my projects, I create a cachingImageView that saves the local image after it downloads. This is inspired by Dawson Toth's work at https://gist.github.com/938172. The only problem is if the image changes on the server once it has been cached locally, the client doesn't get the updated image unless the file name changes. Code is below.

    exports.createCachingImageView = function(params) {
        var image = Ti.UI.createImageView();
    
        image.doRemote = function(imageURL) {
            image.remoteImage = imageURL;
            var file = Ti.Filesystem.getFile(somedirectory, image.localFileName(imageURL));
    
            if(!file.exists()) {
                 // cached file does not exist, load the image
                image.addEventListener("load", image.saveImageOnLoad);
                image.image = imageURL;
            } else {
                Ti.API.debug(image.localFileName(imageURL) + ' does exist, just setting image');
                image.image = file.nativePath;
            }
        };
    
        image.saveImageOnLoad = function(e) {
            Ti.API.debug('saving image ' + image.localFileName(image.remoteImage));
            var f = Ti.Filesystem.getFile(somedirectory, image.localFileName(image.remoteImage));
            if(!f.read()) {
                f.write(e.source.toBlob());
            }
            e.source.removeEventListener('load', image.saveImageOnLoad);
        };
    
        image.localFileName = function(imageURL) {
            hashedSource = Ti.Utils.md5HexDigest(imageURL + '');
            return hashedSource;
        };
        if(params.image) {
            image.doRemote(params.image);
        }
    
        for(var v in params) {
            if(v != 'image') {
                image[v] = params[v];
            }
        }
    
        return image;
    };
    

    If you want to download the image stand alone without using an imageView, use a Ti.Network.httpClient to get the image and save it to the file system like so:

    xhr.onload = function(){    
      var file = Ti.Filesystem.getFile(somedirectory, somefilename );
      file.write(this.responseData);
    }
    

    I use this to fetch images ahead of time so they should right away when the client uses them.