Local Caching of Remote Images in AIR for Android
2013-01-30 17:15
288 查看
转自:http://remotesynthesis.com/post.cfm/local-caching-of-remote-images-in-air-for-android
I was working on an application (some of which will be featured in the upcoming Adobe Edge) that used several images delivered by an API remotely over the web. When working with mobile applications where data is often being delivered by wireless 3G connections of varying signal strengths/speeds, downloading even small(ish) images can be costly and slow. The other thing that you may notice is that if an image component in your Flex "Hero" mobile application is bound to a remote URL, it will reload every time the view is reactivated - meaning you can incur that cost repeatedly. In my case I used your Xbox Live profile tile on the header of most of my applications pages so the delay was blatantly obvious as I pushed and popped views.
Thankfully, AIR for Android and thereby mobile Flex "Hero," has full access to the file API as you would on the desktop. Using the file API I was able to download and store the image locally and simply display the image from my local device storage, eliminating the delay on all subsequent loads - even when the application is closed and reloaded. Here's how.
First of all, within my mobile View I declared a variable for my URLLoader class:
As I stated, in my case the remote image URL was being returned by an API call. Within the result handler for this call, I went ahead and added the following lines of ActionScript to begin the process of downloading the image using the URLLoader:
As you may notice, I have added 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:
The specifics of the File API in AIR actually remain the same here as they would on the desktop. First, I create a reference to the file within the application storage directory. Next I delete the file if it already exists (not sure this is necessary actually). 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.
One thing I noticed in my testing was that 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 (which is a Nexus One) even though it did in the simulator. I'm not entirely sure why that is and if that is the expected behavior on mobile, but this is why I manually set the source property - which works fine. However, this means that, assuming the image exists on disk, you will need to set this property when the view loads. I did this in the ViewActivate handler:
In the end this technique worked great for handling the images I was pulling off this API. Depite the initial load time on the first time load, every time following loaded quickly, even when the application was closed or shut down completely. I was even able to display the cached version while I checked and loaded a newer version if one existed. The key is, the API's you were used to using in AIR still work on Android - and that's an amazing thing in my opinion.
I was working on an application (some of which will be featured in the upcoming Adobe Edge) that used several images delivered by an API remotely over the web. When working with mobile applications where data is often being delivered by wireless 3G connections of varying signal strengths/speeds, downloading even small(ish) images can be costly and slow. The other thing that you may notice is that if an image component in your Flex "Hero" mobile application is bound to a remote URL, it will reload every time the view is reactivated - meaning you can incur that cost repeatedly. In my case I used your Xbox Live profile tile on the header of most of my applications pages so the delay was blatantly obvious as I pushed and popped views.
Thankfully, AIR for Android and thereby mobile Flex "Hero," has full access to the file API as you would on the desktop. Using the file API I was able to download and store the image locally and simply display the image from my local device storage, eliminating the delay on all subsequent loads - even when the application is closed and reloaded. Here's how.
First of all, within my mobile View I declared a variable for my URLLoader class:
private var urlLoader:URLLoader = new URLLoader();
As I stated, in my case the remote image URL was being returned by an API call. Within the result handler for this call, I went ahead and added the following lines of ActionScript to begin the process of downloading the image using the URLLoader:
// since these images load slowly over phone, I will just load and cache them locally urlLoader.dataFormat = URLLoaderDataFormat.BINARY; urlLoader.load(new URLRequest(URL_OF_IMAGE)); urlLoader.addEventListener(Event.COMPLETE,tileLoaded);
As you may notice, I have added 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, I create a reference to the file within the application storage directory. Next I delete the file if it already exists (not sure this is necessary actually). 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.
One thing I noticed in my testing was that 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 (which is a Nexus One) even though it did in the simulator. I'm not entirely sure why that is and if that is the expected behavior on mobile, but this is why I manually set the source property - which works fine. However, this means that, assuming the image exists on disk, you will need to set this property when the view loads. I did this in the ViewActivate handler:
// 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;
In the end this technique worked great for handling the images I was pulling off this API. Depite the initial load time on the first time load, every time following loaded quickly, even when the application was closed or shut down completely. I was even able to display the cached version while I checked and loaded a newer version if one existed. The key is, the API's you were used to using in AIR still work on Android - and that's an amazing thing in my opinion.
相关文章推荐
- one mail for difference between LOCAL_LDLIBS and LOCAL_SHARED_LIBRARIES of Android
- switch、air-conditioner、apply for a postion、modest pension、in honor of
- 【NDN IoT】Caching in Named Data Networking for the Wireless Internet of Things 全文翻译
- Local image caching solution for Android: Square Picasso vs Universal Image Loader
- Error:Could not get unknown property ‘apkVariantData’ for object of type com.android.build.gradle.in
- Development and remote installation of Java service for the Android Devices
- android in practice_Using a Service for caching data(portfolio project)
- 图割论文阅读笔记:Interactive Graph Cuts for Optimal Boundary & Region Segmentation of Objects in N-D Images
- Interactive Graph Cuts for Optimal Boundary and Region Segmentation of Objects in N-D ImageS
- for...in与for...of的区别
- State of the "Art": A Taxonomy of Artistic Stylization Techniques for Images and Video(六)
- Use SQLite Instead of Local Storage In Ionic Framework
- JS迭代器之for-in(of)
- [TroubleShooting] The remote copy of database xx has not been rolled forward to a point in time
- How to add,edit and delete key-value in localStorage of Browse
- best strategies for implementation of equals() and hashcode() in your persistent classes
- The Implementation of A2DP Sink in Android 4.4
- Is there any way to define a min and max value for edittext in android?
- “Location of the Android SDK has not been set up in the preferences”问题的解决
- ionic2打包安卓报错:Error: Could not find an installed version of Gradle either in Android Studio