How to handle Downloading Images on Android

Possible duplicate:
Android - How to make lazy loading of images in ListView

I have been trying to figure this out for a few days, but it seems like I can't think about this process. My application is accessing the number of images from the server. This is currently the setting to upload 1 image at a time and display. When the user clicks the next button, the next image is then downloaded and displayed. But the loading time is too long. What can be done to improve the loading time of the next image?

I played with streams and AsyncTask. My idea was to store previous and next images in memory too. When the user clicks next, I do the following:

prevImage = currentImage; currentImage = nextImage; nextImage = getBitmapfromURL(urlPath); 

And nextImage is actually executed in AsyncTask or Thread. My problem is that the user presses the next button until this stream ends (which just shows a blank image). So I'm not sure if this is the way to go. Is there any other way to improve the loading time of these images? Any ideas would be appreciated.

+4
source share
1 answer

Here is my class for downloading images from the server.

`

 package test; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.net.URL; import java.util.HashMap; import java.util.Stack; import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.drawable.BitmapDrawable; import android.widget.ImageView; import com.com.app.R; public class ImageLoader { // the simplest in-memory cache implementation. This should be replaced with // something like SoftReference or BitmapOptions.inPurgeable(since 1.6) private HashMap<String, Bitmap> cache = new HashMap<String, Bitmap>(); private File cacheDir; public ImageLoader(Context context) { // Make the background thead low priority. This way it will not affect // the UI performance photoLoaderThread.setPriority(Thread.NORM_PRIORITY - 1); // Find the dir to save cached images if (android.os.Environment.getExternalStorageState().equals( android.os.Environment.MEDIA_MOUNTED)) cacheDir = new File( android.os.Environment.getExternalStorageDirectory(), "LazyList"); else cacheDir = context.getCacheDir(); if (!cacheDir.exists()) cacheDir.mkdirs(); } final int stub_id = R.drawable.no_image; public void DisplayImage(String url, Activity activity, ImageView imageView) { if (cache.containsKey(url)) imageView.setImageBitmap(cache.get(url)); else { queuePhoto(url, activity, imageView); imageView.setImageResource(stub_id); } } private void queuePhoto(String url, Activity activity, ImageView imageView) { // This ImageView may be used for other images before. So there may be // some old tasks in the queue. We need to discard them. photosQueue.Clean(imageView); PhotoToLoad p = new PhotoToLoad(url, imageView); synchronized (photosQueue.photosToLoad) { photosQueue.photosToLoad.push(p); photosQueue.photosToLoad.notifyAll(); } // start thread if it not started yet if (photoLoaderThread.getState() == Thread.State.NEW) photoLoaderThread.start(); } private Bitmap getBitmap(String url) { // // I identify images by hashcode. Not a perfect solution, good for // the // // demo. // String filename = String.valueOf(url.hashCode()); // File f = new File(cacheDir, filename); // // // from SD cache // Bitmap b = decodeFile(f); // if (b != null) // return b; // from web try { return new BitmapDrawable(new URL(url).openStream()).getBitmap(); } catch (Exception ex) { ex.printStackTrace(); 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; BitmapFactory.decodeStream(new FileInputStream(f), null, o); // Find the correct scale value. It should be the power of 2. final int REQUIRED_SIZE = 70; 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++; } // decode with inSampleSize BitmapFactory.Options o2 = new BitmapFactory.Options(); o2.inSampleSize = scale; return BitmapFactory.decodeStream(new FileInputStream(f), null, o2); } catch (FileNotFoundException e) { } return null; } // Task for the queue private class PhotoToLoad { public String url; public ImageView imageView; public PhotoToLoad(String u, ImageView i) { url = u; imageView = i; } } PhotosQueue photosQueue = new PhotosQueue(); public void stopThread() { photoLoaderThread.interrupt(); } // stores list of photos to download class PhotosQueue { private Stack<PhotoToLoad> photosToLoad = new Stack<PhotoToLoad>(); // removes all instances of this ImageView public void Clean(ImageView image) { for (int j = 0; j < photosToLoad.size();) { if (photosToLoad.get(j).imageView == image) photosToLoad.remove(j); else ++j; } } } class PhotosLoader extends Thread { public void run() { try { while (true) { // thread waits until there are any images to load in the // queue if (photosQueue.photosToLoad.size() == 0) synchronized (photosQueue.photosToLoad) { photosQueue.photosToLoad.wait(); } if (photosQueue.photosToLoad.size() != 0) { PhotoToLoad photoToLoad; synchronized (photosQueue.photosToLoad) { photoToLoad = photosQueue.photosToLoad.pop(); } Bitmap bmp = getBitmap(photoToLoad.url); cache.put(photoToLoad.url, bmp); if (photoToLoad.url == null) { photoToLoad.url = "http://192.168.0.2/phpdemoprojects/cardsonmobile/uploads/cards/0009.png"; } else { if (((String) photoToLoad.imageView.getTag()) .equals(photoToLoad.url)) { BitmapDisplayer bd = new BitmapDisplayer(bmp, photoToLoad.imageView); Activity a = (Activity) photoToLoad.imageView .getContext(); a.runOnUiThread(bd); } } } if (Thread.interrupted()) break; } } catch (InterruptedException e) { // allow thread to exit } } } PhotosLoader photoLoaderThread = new PhotosLoader(); // Used to display bitmap in the UI thread class BitmapDisplayer implements Runnable { Bitmap bitmap; ImageView imageView; public BitmapDisplayer(Bitmap b, ImageView i) { bitmap = b; imageView = i; } public void run() { if (bitmap != null) imageView.setImageBitmap(bitmap); else imageView.setImageResource(stub_id); } } public void clearCache() { // clear memory cache cache.clear(); // clear SD cache File[] files = cacheDir.listFiles(); for (File f : files) f.delete(); } } 

`

I hope this helps you

+1
source

Source: https://habr.com/ru/post/1340652/


All Articles