Hi ,

i am using following attached three class to download images in my list 
view but when i display some of images on screen after that  i got out of 
memory error and hang the application.in my app i am download thousands of 
images on a single screen. is it possible or not??.

Thanks

On Thursday, May 17, 2012 10:22:19 AM UTC+5:30, huberte wrote:
>
> I used the method from Renaud here
>
>
> http://stackoverflow.com/questions/7524725/android-passing-variable-from-intent-extra-to-imageview/10604079#10604079
>
> This works fine on 2.1 2.3 phone and AVD when I tunr the phone from 
> landscpae to portrait and vice versa
>
> Not in 4.03 phone and AVD, I get a java.lang.OutOfMemoryError, note that 
> my bitmap eg, my png file is only 189ko heavy
>
>     05-17 04:29:53.532: E/AndroidRuntime(1227): FATAL EXCEPTION: main
>     05-17 04:29:53.532: E/AndroidRuntime(1227): java.lang.OutOfMemoryError
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.graphics.Bitmap.nativeCreate(Native Method)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.graphics.Bitmap.createBitmap(Bitmap.java:6    05)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.graphics.Bitmap.createBitmap(Bitmap.java:551)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.graphics.Bitmap.createScaledBitmap(Bitmap.java:437)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.graphics.BitmapFactory.finishDecode(BitmapFactory.java:524)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:499)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:351)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:374)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:404)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> com.android.fbd.Images.onCreate(Images.java:35)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.app.Activity.performCreate(Activity.java:4465)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3351)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.app.ActivityThread.access$700(ActivityThread.java:123)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.app.ActivityThread$H.handleMessage(ActivityThread.java:1151)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.os.Handler.dispatchMessage(Handler.java:99)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.os.Looper.loop(Looper.java:137)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.app.ActivityThread.main(ActivityThread.java:4424)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> java.lang.reflect.Method.invokeNative(Native Method)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> java.lang.reflect.Method.invoke(Method.java:511)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> dalvik.system.NativeStart.main(Native Method)
>

On Thursday, May 17, 2012 10:22:19 AM UTC+5:30, huberte wrote:
>
> I used the method from Renaud here
>
>
> http://stackoverflow.com/questions/7524725/android-passing-variable-from-intent-extra-to-imageview/10604079#10604079
>
> This works fine on 2.1 2.3 phone and AVD when I tunr the phone from 
> landscpae to portrait and vice versa
>
> Not in 4.03 phone and AVD, I get a java.lang.OutOfMemoryError, note that 
> my bitmap eg, my png file is only 189ko heavy
>
>     05-17 04:29:53.532: E/AndroidRuntime(1227): FATAL EXCEPTION: main
>     05-17 04:29:53.532: E/AndroidRuntime(1227): java.lang.OutOfMemoryError
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.graphics.Bitmap.nativeCreate(Native Method)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.graphics.Bitmap.createBitmap(Bitmap.java:6    05)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.graphics.Bitmap.createBitmap(Bitmap.java:551)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.graphics.Bitmap.createScaledBitmap(Bitmap.java:437)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.graphics.BitmapFactory.finishDecode(BitmapFactory.java:524)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:499)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:351)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:374)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:404)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> com.android.fbd.Images.onCreate(Images.java:35)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.app.Activity.performCreate(Activity.java:4465)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3351)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.app.ActivityThread.access$700(ActivityThread.java:123)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.app.ActivityThread$H.handleMessage(ActivityThread.java:1151)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.os.Handler.dispatchMessage(Handler.java:99)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.os.Looper.loop(Looper.java:137)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> android.app.ActivityThread.main(ActivityThread.java:4424)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> java.lang.reflect.Method.invokeNative(Native Method)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> java.lang.reflect.Method.invoke(Method.java:511)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
>     05-17 04:29:53.532: E/AndroidRuntime(1227): at 
> dalvik.system.NativeStart.main(Native Method)
>

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
package utils;

import java.io.File;
import android.content.Context;

public class FileCache {

	private  File cacheDir;

	public FileCache(Context context) {
		// 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();
	}

	public File getFile(String url) {
		// I identify images by hashcode. Not a perfect solution, good for the
		// demo.
		String filename = String.valueOf(url.hashCode());
		// Another possible solution (thanks to grantland)
		// String filename = URLEncoder.encode(url);
		File f = new File(cacheDir, filename);
		return f;

	}

	public  void clear() {
		File[] files = cacheDir.listFiles();
		if (files == null)
			return;
		for (File f : files)
			f.delete();
	}

}
package utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.net.Authenticator;
import java.net.HttpURLConnection;
import java.net.PasswordAuthentication;
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;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.widget.ImageView;

import com.table.R;

public class ImageLoader {

	MemoryCache memoryCache = new MemoryCache();
	FileCache fileCache;
	private Map<ImageView, String> imageViews = Collections
			.synchronizedMap(new WeakHashMap<ImageView, String>());
	ExecutorService executorService;

	public ImageLoader(Context context) {
		fileCache = new FileCache(context);
		executorService = Executors.newFixedThreadPool(5);
	}

	final int stub_id = R.drawable.default_image;

	public void DisplayImage(String url, ImageView imageView) {
		imageViews.put(imageView, url);
		Bitmap bitmap = memoryCache.get(url);
		if (bitmap != null) {
			imageView.setImageBitmap(bitmap);
		} else {
			queuePhoto(url, imageView);
			imageView.setImageResource(stub_id);
		}
	}

	private void queuePhoto(String url, ImageView imageView) {
		PhotoToLoad p = new PhotoToLoad(url, imageView);
		executorService.submit(new PhotosLoader(p));
	}

	private Bitmap getBitmap(String url) {
		File f = fileCache.getFile(url);
		// from SD cache
		Bitmap b = decodeFile(f);
		if (b != null)
			return b;

		// from web
		try {

			Authenticator.setDefault(new Authenticator() {

				protected PasswordAuthentication getPasswordAuthentication() {

					return new PasswordAuthentication(Constant.user_name,
							Constant.password.toCharArray());
				}

			});

			URL urll = new URL(url.toString());
			HttpURLConnection connection = (HttpURLConnection) urll
					.openConnection();
			connection.setDoInput(true);
			connection.setUseCaches(false);
			connection.setChunkedStreamingMode(1000 * 1024);
			connection.setRequestProperty("Connection", "Keep-Alive");
			connection.connect();

			InputStream input = connection.getInputStream();
			Bitmap myBitmap = BitmapFactory.decodeStream(input);
			// Log.e("Bitmap", "returned");
			return myBitmap;
		} 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 = 10;
			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 inSampleSize
			BitmapFactory.Options o2 = new BitmapFactory.Options();
			o2.inPurgeable = true;
			o2.inSampleSize = scale;
			return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
		} catch (FileNotFoundException e) {
			e.fillInStackTrace();
		}
		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;
		}
	}

	class PhotosLoader implements Runnable {
		PhotoToLoad photoToLoad;

		PhotosLoader(PhotoToLoad photoToLoad) {
			this.photoToLoad = photoToLoad;
		}

		@Override
		public void run() {
			if (imageViewReused(photoToLoad))
				return;
			Bitmap bmp = getBitmap(photoToLoad.url);
			// bmp = resizeImage(bmp,60,60);
			// memoryCache.put(photoToLoad.url, bmp);

			if (imageViewReused(photoToLoad))
				return;
			BitmapDisplayer bd = new BitmapDisplayer(bmp, photoToLoad);
			Activity a = (Activity) photoToLoad.imageView.getContext();
			a.runOnUiThread(bd);
		}
	}

	boolean imageViewReused(PhotoToLoad photoToLoad) {
		String tag = imageViews.get(photoToLoad.imageView);
		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;
			if (bitmap != null) {
				photoToLoad.imageView.setImageBitmap(bitmap);
				fileCache.clear();

			} else
				photoToLoad.imageView.setImageResource(stub_id);

		}
	}

	public void clearCache() {
		memoryCache.clear();
		fileCache.clear();
	}

	public static Bitmap resizeImage(Bitmap bitmap, int w, int h) {

		int width = bitmap.getWidth();
		int height = bitmap.getHeight();
		int newWidth = w;
		int newHeight = h;

		float scaleWidth = ((float) newWidth) / width;
		float scaleHeight = ((float) newHeight) / height;

		Matrix matrix = new Matrix();
		matrix.postScale(scaleWidth, scaleHeight);

		Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height,
				matrix, true);
		return resizedBitmap;
	}
}
package utils;

import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;

import android.graphics.Bitmap;
import android.util.Log;

public class MemoryCache {

	private static final String TAG = "MemoryCache";
	// private Map<String, Bitmap> cache = Collections
	// .synchronizedMap(new LinkedHashMap<String, Bitmap>(10, 1.5f, true));//
	// Last
	// argument
	// true
	// for
	// LRU
	// ordering
	private HashMap<String, SoftReference<Bitmap>> cache;
	private long size = 0;// current allocated size
	private long limit = 1000000;// max memory in bytes

	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).get();
		} catch (NullPointerException ex) {
			return null;
		}
	}

	public void put(String id, Bitmap bitmap) {
		try {
			if (cache.containsKey(id))
				// size -= getSizeInBytes(cache.get(id).get());
				cache.put(id, new SoftReference<Bitmap>(bitmap));
			// size += getSizeInBytes(bitmap);
			checkSize();
		} catch (Throwable th) {
			th.printStackTrace();
		}
	}

	public void checkSize() {
		Log.i(TAG, "cache size=" + size + " length=" + cache.size());
		if (size > limit) {
			Iterator<Entry<String, SoftReference<Bitmap>>> iter = cache
					.entrySet().iterator();
			while (iter.hasNext()) {
				Entry<String, SoftReference<Bitmap>> entry = iter.next();
				size -= getSizeInBytes(entry.getValue().get());
				iter.remove();
				if (size <= limit)
					break;
			}
			Log.i(TAG, "Clean cache. New size " + cache.size());
		}
	}

	public void clear() {
		cache.clear();
	}

	long getSizeInBytes(Bitmap bitmap) {
		if (bitmap == null)
			return 0;
		return bitmap.getRowBytes() * bitmap.getHeight();
	}
}

Reply via email to