Avg. Rating 5.0

Problem

I have an image being served from a remote URL but I would like to copy that image to local device storage to serve it up faster and when the application is offline.

Solution

AIR for Android (and thereby mobile Flex) has access to the same file API you are accustomed to in standard desktop AIR application programming. You can utilize this to create a local copy of the remote image and serve this up when offline or simply for faster display.

Detailed explanation

AIR for Android has full access to the file API as you use for desktop AIR development. Using the file API can download and store the image locally and simply display the image from the local device storage, eliminating delay on all subsequent loads or when the application is offline.

First of all, within the View, declare a variable for the URLLoader class:

private var urlLoader:URLLoader = new URLLoader();

In this scenario the remote image URL was being returned by an API call, so within the result handler for this call you would add the following lines of ActionScript to begin the process of downloading the image using the URLLoader:

 

urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
urlLoader.load(new URLRequest(URL_OF_IMAGE));
urlLoader.addEventListener(Event.COMPLETE,tileLoaded);

As you may notice, the above code has an event listener for when this download is complete. Let's take a look at the handler for this, which is where we get into the File API:

protected function tileLoaded(event:Event):void {
   var tilefile:File = File.applicationStorageDirectory.resolvePath("tile.png");
   if (tilefile.exists) {
      tilefile.deleteFile();
   }
   var fileStream:FileStream = new FileStream();
   fileStream.open(tilefile, FileMode.WRITE);
   fileStream.writeBytes(urlLoader.data);
   fileStream.close(); 
   
   myImageComponent.source = tilefile.url;
}

The specifics of the File API in AIR actually remain the same here as they would on the desktop. First, create a reference to the file within the application storage directory. Next delete the file if it already exists (this may not be required). Next I write out the image to disk using a filestream. Once this is complete, I change the source of the image component in my View to the locally stored image.

In my testing, binding to the local image using the normal AIR file prefixes or the above File.url property didn't seem to work on the phone (a Nexus One) even though it did in the simulator. Manually setting the source property works fine though. This means that, assuming the image exists on disk, you will need to set this property when the view loads. You can do this in the ViewActivate handler with the following code:

// see if we can just use a local copy of the tile
var tilefile:File = File.applicationStorageDirectory.resolvePath("tile.png");
if (tilefile.exists)
   myGamerimage.source = tilefile.url;

Despite the initial load time on the first time load, every subsequent load was extremely quick, even when the application was closed or shut down completely or the phone was offline.

This post was excerpted from my blog post at  http://remotesynthesis.com/post.cfm/local-caching-of-remote-images-in-air-for-android. Please visit my blog for regular posts on Flex and ActionScript.


+
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License. Permissions beyond the scope of this license, pertaining to the examples of code included within this work are available at Adobe.

Report abuse

Related recipes