Android asynchronous image loading method 2 (2)

Source: Internet
Author: User

Filecache. Java is as follows:

Package com.cn. loadImages; import java. io. file; import java. io. fileNotFoundException; import java. io. fileOutputStream; import java. io. IOException; import java. io. inputStream; import java. io. outputStream; import android. content. context; import android.net. uri; import android. util. log; public class FileCache {private File cacheDir; public FileCache (Context context) {if (android. OS. environment. getExternalStorage State (). equals (android. OS. environment. MEDIA_MOUNTED) {cacheDir = new File (android. OS. environment. getExternalStorageDirectory (), "ltcImageCache");} else {cacheDir = context. getCacheDir ();} if (cacheDir! = Null &&! CacheDir. exists () {Utils. doMkdir (cacheDir) ;}// create a folder on the SD card to save the image public FileCache (Context context, String path) {if (android. OS. environment. getExternalStorageState (). equals (android. OS. environment. MEDIA_MOUNTED) {cacheDir = new File (android. OS. environment. getExternalStorageDirectory () + File. separator + path); Log. I ("xx", "cacheDir =" + cacheDir. toString ();} if (cacheDir! = Null &&! CacheDir. exists () {Utils. doMkdir (cacheDir) ;}// Save the image to public boolean addToFileCache (String url, InputStream inputStream, long size) in the file (SD card) after the download is completed {boolean isrenbturitmap = true; outputStream outputStream = null; try {if (! Utils. canSave (size) {return false;} File file = getFromFileCache (url); if (file = null) {return false;} outputStream = new FileOutputStream (file ); copyStream (inputStream, outputStream);} catch (FileNotFoundException e) {e. printStackTrace (); isReturnBitmap = false;} catch (Exception e) {isReturnBitmap = false;} finally {if (outputStream! = Null) {try {outputStream. close ();} catch (IOException e) {e. printStackTrace () ;}}return isReturnBitmap;} // Filepublic File getFromFileCache (String url) {String fileName = getImageNameFromUrl (url) for each image ); if (cacheDir = null) {return null;} File file = new File (cacheDir, fileName); return file ;} // Delete the public void upload AchE () {if (cacheDir = null) {return;} File [] files = cacheDir. listFiles (); If (files = null) return; for (File f: files) f. delete ();} public void deleteIncompleteCache (String url) {File file = getFromFileCache (url); if (file! = Null & file. exists () {file. delete () ;}/// extract the file name from the image url. private String getImageNameFromUrl (String url) {Uri uri Uri = Uri. parse (url); String imageName = uri. getLastPathSegment (); return imageName;} // stream operation private void copyStream (InputStream inputStream, OutputStream outputStream) {final int buffer_size = 1024; try {byte [] bytes = new byte [buffer_size]; for (;) {int count = inputStream. read (bytes, 0, buffer_size); if (count =-1) break; outputStream. write (bytes, 0, count) ;}} catch (Exception ex ){}}}

Imagecache. Java is as follows:

Package com.cn. loadimages; import Java. lang. ref. softreference; import Java. util. hashmap; import Java. util. linkedhashmap; import Java. util. concurrent. concurrenthashmap; import android. graphics. bitmap; import android. OS. handler;/*** cache-related fields and methods. ** we use a hard and a soft cache. A soft reference cache is too aggressively * cleared by the garbage collector. ** // This is the cache in the memory. // two levels of shar Dbitmapcache and ssoftbitmapcachepublic class imagecache {Private Static final int hard_cache_capacity = 30; Private Static final int delay_before_purge = 60*1000; // in milliseconds // hard cache, with a fixed maximum capacity and a life duration @ suppresswarnings ("serial") private final hashmap <string, bitmap> shardbitmapcache = new linkedhashmap <string, bitmap> (Bytes/2, 0.75f, true ){ @ Overrideprotected Boolean removeeldestentry (linkedhashmap. entry <string, bitmap> eldest) {If (SIZE ()> hard_cache_capacity) {// entries push-out of Hard reference cache are transferred to soft reference cache // when the size in shardbitmapcache is greater than the rated capacity hard_cache_capacity, // put the oldest shardbitmapcache object in ssoftbitmapcache, objects in // ssoftbitmapcache are more likely to be recycled by GC. put (eldest. getkey (), new softreference <bitmap> (Eldest. getvalue (); Return true;} elsereturn false ;}}; // soft cache for bitmaps kicked out of hard cacheprivate final static concurrenthashmap <string, softreference <bitmap> ssoftbitmapcache = new concurrenthashmap <string, softreference <bitmap> (hard_cache_capacity/2); private final handler purgehandler = new handler (); // used to clear (purger) runnableprivate final runna of ssoftbitmapcache and shardbitmapcache Ble purger = new runnable () {public void run () {// shareache () ;}}; // put the bitmap in the memory (shardbitmapcache) after the download is complete) public void addbitmaptocache (string URL, Bitmap bitmap) {If (Bitmap! = NULL) {synchronized (shardbitmapcache) {shardbitmapcache. put (URL, bitmap) ;}}// obtain the image public bitmap getbitmapfromcache (string URL) from imagecache) {// first try the Hard reference cache // first obtain the picture synchronized (shardbitmapcache) {final Bitmap bitmap = shardbitmapcache from the shardbitmapcache. get (URL); If (Bitmap! = NULL) {// bitmap found in hard cache // move element to first position, so that it is removed last // now that you want to get this image, this image is recently used. // all objects are the latest objects. // remove the object from the shardbitmapcache first // insert it to the front of the shardbitmapcache. remove (URL); shardbitmapcache. put (URL, bitmap); Return bitmap;} else {}}// if the object is not in shardbitmapcache, it may be because the object is too old. // it has already been stored in ssoftbitmapcache. // so try to get the object from ssoftbitmapcache // then try the S Oft reference cachesoftreference <bitmap> bitmapreference = ssoftbitmapcache. Get (URL); If (bitmapreference! = NULL) {final Bitmap bitmap = bitmapreference. Get (); If (Bitmap! = NULL) {// bitmap found in soft cachereturn bitmap;} else {// soft reference has been garbage collectedssoftbitmapcache. remove (URL) ;}} else {}return NULL;}/*** clears the image cache used internally to improve performance. note that * For memory efficiency reasons, the cache will automatically be cleared * after a certain inactivity delay. */private void upload AchE () {shardbitmapcache. clear (); ssoft Bitmapcache. clear ();}/*** allow a new delay before the automatic cache clear is done. */Public void resetpurgetimer () {purgehandler. removecallbacks (purger); purgehandler. postdelayed (purger, delay_before_purge);} public void removefromcache (string URL) {If (shardbitmapcache! = NULL) {shardbitmapcache. Remove (URL);} If (ssoftbitmapcache! = NULL) {ssoftbitmapcache. Remove (URL) ;}system. GC ();}}

Imagedownloader. Java is as follows:

Package com.cn. loadImages; import java. io. file; import java. io. fileInputStream; import java. io. fileNotFoundException; import java. io. filterInputStream; import java. io. IOException; import java. io. inputStream; import java. lang. ref. weakReference; import org. apache. http. httpEntity; import org. apache. http. httpResponse; import org. apache. http. httpStatus; import org. apache. http. client. httpClient; import org. apache. ht Tp. client. methods. httpGet; import org. apache. http. impl. client. defaultHttpClient; import android. content. context; import android. graphics. bitmap; import android. graphics. bitmapFactory; import android. graphics. color; import android. graphics. drawable. colorDrawable; import android. graphics. drawable. drawable; import android.net. http. androidHttpClient; import android. OS. asyncTask; import android. widget. imageView; // Reference: // http://blog.csdn.net/icephone/article/details/7517865//http://www.cnblogs.com/shyang--TechBlogs/archive/2011/03/24/1994080.htmlpublic class ImageDownloader {private ImageCache imageCache; private FileCache fileCache; // constructor public ImageDownloader (Context context, String localStoragePath) {imageCache = new ImageCache (); // create a folder on the SD card to save the image fileCache = new FileCache (context, localStoragePath );}/* ** Download the specified image from the Internet and binds it to the * provided ImageView. the binding is immediate if the image is found in the * cache and will be done asynchronously otherwise. A null bitmap will be * associated to the ImageView if an error occurs. */public void download (String url, final ImageView imageView) {// purge clears imageCache. resetPurgeTimer (); // first try to obtain the image Bitmap bitmap from the memory = ImageCache. getBitmapFromCache (url); if (bitmap = null) {forceDownload (url, imageView);} else {// if the image already exists, cancel the potential downloading of the image cancelPotentialDownload (url, imageView); imageView. setImageBitmap (bitmap);}/*** Same as download but the image is always downloaded and the cache is not * used. kept private at the moment as its interest is not clear. * /// Method for downloading images private void forceDownload (String imageUrl, ImageView I MageView) {if (imageUrl = null) {return;} if (cancelPotentialDownload (imageUrl, imageView )) {// 1 create a BitmapDownloaderTask asynchronous task // you can see through the construction method of BitmapDownloaderTask: // This BitmapDownloaderTask weakly references this iamgeView. // Note :!!!!!!!!!!!!!!!!!!!!! // In the construction method of BitmapDownloaderTask, // This BitmapDownloaderTask maintains a weak reference to imageView. // At the same time, the DownloadedDrawable constructor maintains a weak reference to BitmapDownloaderTask // therefore, BitmapDownloaderTask and ImageView form a binding relationship between weak references !!!! BitmapDownloaderTask bitmapDownloaderTask = new BitmapDownloaderTask (imageView); // 2. Create a DownloadedDrawable. // you can see through the DownloadedDrawable construction method: // This DownloadedDrawable weak reference to this bitmapDownloaderTask DownloadedDrawable downloadedDrawable = new DownloadedDrawable (bitmapDownloaderTask); // 3 imageView displays a specified color (Drawable) if (imageView! = Null) {// when the image download is incomplete, the imageView loads the downloadedDrawable // It is super (Color. the specified imageView color. setImageDrawable (downloadedDrawable);} bitmapDownloaderTask. setUrl (imageUrl); // 4 Export cute (imageUrl) ;}}// cancel potential download private static boolean cancelPotentialDownload (String url, ImageView imageView) {BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask (imag) EView); if (bitmapDownloaderTask! = Null) {String bitmapUrl = bitmapDownloaderTask. url; if (bitmapUrl = null) | (! BitmapUrl. equals (url) {bitmapDownloaderTask. cancel (true);} else {return false;} return true;}/** An InputStream that skips the exact number of bytes provided, unless it reaches EOF. */static class FlushedInputStream extends FilterInputStream {public FlushedInputStream (InputStream inputStream) {super (inputStream) ;}@ Overridepublic long skip (long n) throws IOException {long timeout = 0L; w Hile (totalBytesSkipped <n) {long bytesSkipped = in. skip (n-totalBytesSkipped); if (bytesSkipped = 0L) {int B = read (); if (B <0) {break; // we reached EOF} else {bytesSkipped = 1; // we read one byte} totalBytesSkipped + = bytesSkipped;} return totalBytesSkipped ;}} // asynchronous task execution download public class BitmapDownloaderTask extends AsyncTask <String, Void, Bitmap> {private String url; private WeakReference <ImageVi Ew> imageViewWeakReference; private Bitmap bitmap = null; private HttpClient httpClient; public String getUrl () {return this. url;} public void setUrl (String _ url) {this. url = _ url;} public BitmapDownloaderTask (ImageView imageView) {// This BitmapDownloaderTask keeps a weak reference to imageView !!! ImageViewWeakReference = new WeakReference <ImageView> (imageView) ;}@ Overrideprotected Bitmap doInBackground (String... params) {boolean download = false; // try to get image from file cache // then try to get the image File file = fileCache from the file (SD card) cache. getFromFileCache (url); try {if (file. exists () {bitmap = BitmapFactory. decodeStream (new FlushedInputStream (new FileInputStream (file);} catch (FileNotFoundException e1) {e1. PrintStackTrace (); bitmap = null;} catch (Exception e) {e. printStackTrace (); bitmap = null;} if (bitmap! = Null) {download = true; return bitmap;} // end of try // The image cannot be obtained from the file (SD card, download httpClient = new DefaultHttpClient (); final HttpGet getRequest = new HttpGet (url); try {HttpResponse httpResponse = httpClient.exe cute (getRequest); final int statusCode = httpResponse. getStatusLine (). getStatusCode (); if (statusCode! = HttpStatus. SC _ OK) {return null;} final HttpEntity httpEntity = httpResponse. getEntity (); if (httpEntity! = Null) {InputStream inputStream = null; try {long size = httpEntity. getContentLength (); inputStream = httpEntity. getContent (); // save file to file cache // operation 1 after the download is complete: save the image in the file (SD card) boolean addResult = fileCache. addToFileCache (url, inputStream, size); // end of save // TODOif (addResult) {download = true; return BitmapFactory. decodeStream (new FlushedInputStream (new FileInputStream (file);} else {download = True; return BitmapFactory. decodeStream (new FlushedInputStream (inputStream);} catch (Exception e) {e. printStackTrace ();} finally {if (inputStream! = Null) {inputStream. close () ;}httpentity. consumeContent () ;}} catch (Exception e) {e. printStackTrace () ;}finally {if (httpClient! = Null) {httpClient. getConnectionManager (). shutdown ();} if (! Download) {fileCache. deleteIncompleteCache (url) ;}} return null ;}@ Overrideprotected void onPostExecute (Bitmap bitmap) {if (isCancelled () {bitmap = null ;} // add bitmap to cache // The operation after the download is completed 2: Save the image in the memory imageCache. addBitmapToCache (url, bitmap); // operation 3 after the download is complete: display the image in the ImageView. // if the image is referenced, it may be recycled by the system, therefore, you must first determine whether the imageViewWeakReference is nullif (imageViewWeakReference! = Null) {// 3.1 obtain the ImageView referenced by the task (corresponding to 1 in forceDownload) ImageView imageView = imageViewWeakReference. get (); // For the getBitmapDownloaderTask method, see (core) // 3.2 to obtain the task corresponding to this imageview (corresponding to 2 in forceDownload) BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask (imageView ); // 3.3 if the current task is the task corresponding to the imageview, set the image of this imageview as the downloaded Bitmapif (this = bitmapDownloaderTask) {imageView. setImageBitmap (bitmap) ;}}@ Overrideprotect Ed void onCancelled () {if (httpClient instanceof AndroidHttpClient) {(AndroidHttpClient) httpClient). close ();} if (bitmap! = Null) {bitmap. recycle (); bitmap = null;} super. onCancelled () ;}}/*** @ param imageView Any imageView * @ return Retrieve the currently active download task (if any) associated * with this imageView. null if there is no such task. */private static BitmapDownloaderTask getBitmapDownloaderTask (ImageView imageView) {if (imageView! = Null) {// In forceDownload 3, imageView only displays a pre-specified color (Drawable) // The pre-specified DrawableDrawable drawable = imageView is obtained here. getDrawable (); if (drawable instanceof DownloadedDrawable) {DownloadedDrawable downloadedDrawable = (DownloadedDrawable) drawable; // because the DownloadedDrawable in forceDownload 2 maintains a weak reference to the bitmapDownloaderTask // you can use this DownloadedDrawable to obtain the bitmapDownloaderTask // getBitmapDownloaderTask method (core) return downloadedDrawable. getBitmapDownloaderTask () ;}} return null;}/*** A fake Drawable that will be attached to the imageView while the download * is in progress. * <p> * Contains a reference to the actual download task, so that a download task * can be stopped if a new binding is required, and makes sure that only the * last started download process can bind its result, independently of the * download finish order. * </p> * // This class contains a weak reference to the download task BitmapDownloaderTask. // Note: // super (Color. TRANSPARENT); // The color displayed by the ImageView when the image is not loaded. static class extends ColorDrawable {private final WeakReference <BitmapDownloaderTask> callback; public DownloadedDrawable (BitmapDownloaderTask bitmapDownloaderTask) {super (Color. TRANSPARENT); response = new WeakReference <BitmapDownloaderTask> (bitmapDownloaderTask);} // obtain a BitmapDownloaderTaskpublic BitmapDownloaderTask getBitmapDownloaderTask () {return response. get ();}}}

Utils. Java is as follows:

Package com.cn. loadImages; import java. io. file; import android. OS. environment; import android. OS. statFs; public class Utils {private static final int ERROR =-1; public static int save_dir = 1; // determine whether the SD card public static boolean isSDCardExist () {return android is installed. OS. environment. getExternalStorageState (). equals (android. OS. environment. MEDIA_MOUNTED);} // public static long getAvailableInternalMemorySize () {File path = Environment. getDataDirectory (); StatFs stat = new StatFs (path. getPath (); long blockSize = stat. getBlockSize (); long availableBlocks = stat. getAvailableBlocks (); return availableBlocks * blockSize;} // total memory space public static long getTotalInternalMemorySize () {File path = Environment. getDataDirectory (); StatFs stat = new StatFs (path. getPath (); long blockSize = stat. getBlockSize (); long totalBlocks = stat. getBlockCount (); return totalBlocks * blockSize;} // remaining space of the SD card public static long getAvailableExternalMemorySize () {if (isSDCardExist () {File path = Environment. getExternalStorageDirectory (); StatFs stat = new StatFs (path. getPath (); long blockSize = stat. getBlockSize (); long availableBlocks = stat. getAvailableBlocks (); return availableBlocks * blockSize;} else {return ERROR ;}// total space of the SD card public static long getTotalExternalMemorySize () {if (isSDCardExist ()) {File path = Environment. getExternalStorageDirectory (); StatFs stat = new StatFs (path. getPath (); long blockSize = stat. getBlockSize (); long totalBlocks = stat. getBlockCount (); return totalBlocks * blockSize;} else {return ERROR ;}// create the public static boolean doMkdir (File dirFile) {try {boolean bFile = dirFile. exists (); if (bFile = true) {return true;} else {bFile = dirFile. mkdirs (); // create successif (bFile = true) {return true;} else {return false ;}} catch (Exception err) {err. printStackTrace (); return false ;}// determines whether public static boolean canSave (long size) can be saved {return getAvailableExternalMemorySize ()> size ;}}

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.