UIL aims to provide a powerful, flexible and highly customizable instrument for image loading, caching and displaying. It provides a lot of configuration options and good control over the image loading and caching process.
- Multithread image loading (async or sync)
- Wide customization of ImageLoader’s configuration (thread executors, downloader, decoder, memory and disk cache, display image options, etc.)
- Many customization options for every display image call (stub images, caching switch, decoding options, Bitmap processing and displaying, etc.)
- Image caching in memory and/or on disk (device’s file system or SD card)
- Listening loading process (including downloading progress)
Android 2.0+ support
Source : GitHub : https://github.com/nostra13/Android-Universal-Image-Loader
Display image from the image loader from the classes : 1) public ImageLoader imageLoader; 2) imageLoader = ImageLoader(Activity.this); 3) yourimageview = (ImageView) findViewById(R.id.yourimageview); imageLoader.DisplayImage(Constants.upload_image_url + imagename + ".png", yourimageview); Required Files : ->FileCache.java ->ImageLoader.java ->ImageLoaderChatImage ->MemoryCache.java ->Utils.java Through universal-image-loader-1.9.4.jar
Direct ImageLoader from the jar and configure with options. try { ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getActivity()) // You can pass your own memory cache implementation .discCacheFileNameGenerator(new HashCodeFileNameGenerator()) .build(); DisplayImageOptions options = new DisplayImageOptions.Builder() .displayer(new RoundedBitmapDisplayer(25)) .cacheInMemory() .cacheOnDisc() .build(); ImageLoader imageLoader = ImageLoader.getInstance(); imageLoader.init(config); imageLoader.displayImage(Constants.fetch_Profile_Image + Constants.user_id + ".png", img_capture_photo, options); // imageLoader.displayImage("url" + Constants.user_id + ".png", img_capture_photo, options); } catch (Exception e) { e.printStackTrace(); } Other Necessary File for Imaage Loader ( Without Jar file ) FileCache.java import android.content.Context; import java.io.File; public class FileCache { private File cacheDir; public FileCache(Context context){ //Find the dir at SDCARD to save cached images if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) { //if SDCARD is mounted (SDCARD is present on device and mounted) cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"LazyList"); } else { // if checking on simulator the create cache dir in your application context cacheDir=context.getCacheDir(); } if(!cacheDir.exists()){ // create cache dir in your application context cacheDir.mkdirs(); } } public File getFile(String url){ //Identify images by hashcode or encode by URLEncoder.encode. String filename=String.valueOf(url.hashCode()); File f = new File(cacheDir, filename); return f; } public void clear(){ // list all files inside cache directory File[] files=cacheDir.listFiles(); if(files==null) return; //delete all cache directory files for(File f:files) f.delete(); } } ImageLoader.java import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Handler; import android.widget.ImageView; import com.tubsystems.beamitup.R; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.Collections; import java.util.Map; import java.util.WeakHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ImageLoader { // Initialize MemoryCache MemoryCache memoryCache = new MemoryCache(); FileCache fileCache; //Create Map (collection) to store image and image url in key value pair private Map<ImageView, String> imageViews = Collections.synchronizedMap(new WeakHashMap<ImageView, String>()); ExecutorService executorService; //handler to display images in UI thread Handler handler = new Handler(); public ImageLoader(Activity context) { fileCache = new FileCache(context); // Creates a thread pool that reuses a fixed number of // threads operating off a shared unbounded queue. executorService = Executors.newFixedThreadPool(5); } // default image show in list (Before online image download) final int stub_id = R.drawable.image_placeholder; public void DisplayImage(String url, ImageView imageView) { //Store image and url in Map imageViews.put(imageView, url); //Check image is stored in MemoryCache Map or not (see MemoryCache.java) Bitmap bitmap = memoryCache.get(url); if (bitmap != null) { // if image is stored in MemoryCache Map then // Show image in listview row imageView.setImageBitmap(bitmap); } else { //queue Photo to download from url queuePhoto(url, imageView); //Before downloading image show default image imageView.setImageResource(stub_id); } } private void queuePhoto(String url, ImageView imageView) { // Store image and url in PhotoToLoad object PhotoToLoad p = new PhotoToLoad(url, imageView); // pass PhotoToLoad object to PhotosLoader runnable class // and submit PhotosLoader runnable to executers to run runnable // Submits a PhotosLoader runnable task for execution executorService.submit(new PhotosLoader(p)); } //Task for the queue private class PhotoToLoad { public String url; public ImageView imageView; public PhotoToLoad(String u, ImageView i) { url = u; imageView = i; } } class PhotosLoader implements Runnable { PhotoToLoad photoToLoad; PhotosLoader(PhotoToLoad photoToLoad) { this.photoToLoad = photoToLoad; } @Override public void run() { try { //Check if image already downloaded if (imageViewReused(photoToLoad)) return; // download image from web url Bitmap bmp = getBitmap(photoToLoad.url); // set image data in Memory Cache memoryCache.put(photoToLoad.url, bmp); if (imageViewReused(photoToLoad)) return; // Get bitmap to display BitmapDisplayer bd = new BitmapDisplayer(bmp, photoToLoad); // Causes the Runnable bd (BitmapDisplayer) to be added to the message queue. // The runnable will be run on the thread to which this handler is attached. // BitmapDisplayer run method will call handler.post(bd); } catch (Throwable th) { th.printStackTrace(); } } } private Bitmap getBitmap(String url) { File f = fileCache.getFile(url); //from SD cache //CHECK : if trying to decode file which not exist in cache return null Bitmap b = decodeFile(f); if (b != null) return b; // Download image file from web try { Bitmap bitmap = null; URL imageUrl = new URL(url); HttpURLConnection conn = (HttpURLConnection) imageUrl.openConnection(); conn.setConnectTimeout(30000); conn.setReadTimeout(30000); conn.setInstanceFollowRedirects(true); InputStream is = conn.getInputStream(); // Constructs a new FileOutputStream that writes to file // if file not exist then it will create file OutputStream os = new FileOutputStream(f); // See Utils class CopyStream method // It will each pixel from input stream and // write pixels to output stream (file) Utils.CopyStream(is, os); os.close(); conn.disconnect(); //Now file created and going to resize file with defined height // Decodes image and scales it to reduce memory consumption bitmap = decodeFile(f); return bitmap; } catch (Throwable ex) { ex.printStackTrace(); if (ex instanceof OutOfMemoryError) memoryCache.clear(); return null; } } //Decodes image and scales it to reduce memory consumption private Bitmap decodeFile(File f) { try { //Decode image size BitmapFactory.Options o = new BitmapFactory.Options(); o.inJustDecodeBounds = true; FileInputStream stream1 = new FileInputStream(f); BitmapFactory.decodeStream(stream1, null, o); stream1.close(); //Find the correct scale value. It should be the power of 2. // Set width/height of recreated image final int REQUIRED_SIZE = 85; int width_tmp = o.outWidth, height_tmp = o.outHeight; int scale = 1; while (true) { if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE) break; width_tmp /= 2; height_tmp /= 2; scale *= 2; } //decode with current scale values BitmapFactory.Options o2 = new BitmapFactory.Options(); o2.inSampleSize = scale; FileInputStream stream2 = new FileInputStream(f); Bitmap bitmap = BitmapFactory.decodeStream(stream2, null, o2); stream2.close(); return bitmap; } catch (FileNotFoundException e) { } catch (IOException e) { e.printStackTrace(); } return null; } boolean imageViewReused(PhotoToLoad photoToLoad) { String tag = imageViews.get(photoToLoad.imageView); //Check url is already exist in imageViews MAP if (tag == null || !tag.equals(photoToLoad.url)) return true; return false; } //Used to display bitmap in the UI thread class BitmapDisplayer implements Runnable { Bitmap bitmap; PhotoToLoad photoToLoad; public BitmapDisplayer(Bitmap b, PhotoToLoad p) { bitmap = b; photoToLoad = p; } public void run() { if (imageViewReused(photoToLoad)) return; // Show bitmap on UI if (bitmap != null) photoToLoad.imageView.setImageBitmap(bitmap); else photoToLoad.imageView.setImageResource(stub_id); } } public void clearCache() { //Clear cache directory downloaded images and stored data in maps memoryCache.clear(); fileCache.clear(); } } MemoryCache.java import android.graphics.Bitmap; import android.util.Log; import java.util.Collections; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; public class MemoryCache { private static final String TAG = "MemoryCache"; //Last argument true for LRU ordering private Map<String, Bitmap> cache = Collections.synchronizedMap( new LinkedHashMap<String, Bitmap>(10,1.5f,true)); //current allocated size private long size=0; //max memory cache folder used to download images in bytes private long limit=1000000; public MemoryCache(){ //use 25% of available heap size setLimit(Runtime.getRuntime().maxMemory()/4); } public void setLimit(long new_limit){ limit=new_limit; Log.i(TAG, "MemoryCache will use up to "+limit/1024./1024.+"MB"); } public Bitmap get(String id){ try{ if(!cache.containsKey(id)) return null; //NullPointerException sometimes happen here http://code.google.com/p/osmdroid/issues/detail?id=78 return cache.get(id); }catch(NullPointerException ex){ ex.printStackTrace(); return null; } } public void put(String id, Bitmap bitmap){ try{ if(cache.containsKey(id)) size-=getSizeInBytes(cache.get(id)); cache.put(id, bitmap); size+=getSizeInBytes(bitmap); checkSize(); }catch(Throwable th){ th.printStackTrace(); } } private void checkSize() { Log.i(TAG, "cache size="+size+" length="+cache.size()); if(size>limit){ Iterator<Entry<String, Bitmap>> iter=cache.entrySet().iterator();//least recently accessed item will be the first one iterated while(iter.hasNext()){ Entry<String, Bitmap> entry=iter.next(); size-=getSizeInBytes(entry.getValue()); iter.remove(); if(size<=limit) break; } Log.i(TAG, "Clean cache. New size "+cache.size()); } } public void clear() { try{ //NullPointerException sometimes happen here http://code.google.com/p/osmdroid/issues/detail?id=78 cache.clear(); size=0; }catch(NullPointerException ex){ ex.printStackTrace(); } } long getSizeInBytes(Bitmap bitmap) { if(bitmap==null) return 0; return bitmap.getRowBytes() * bitmap.getHeight(); } } Utils.java import java.io.InputStream; import java.io.OutputStream; public class Utils { public static void CopyStream(InputStream is, OutputStream os) { final int buffer_size=1024; try { byte[] bytes=new byte[buffer_size]; for(;;) { //Read byte from input stream int count=is.read(bytes, 0, buffer_size); if(count==-1) break; //Write byte from output stream os.write(bytes, 0, count); } } catch(Exception ex){} } }