2

In my application i am downloading images from the web. i got the out memory exception. somebody suggests that clear heap using the following code. But still i am facing the out of memory exception.can anybody help me. The following method is called when the activity is started. Here I refer to this link

 public void onStart()
{ 
 super.onStart(); 
 //Handling the out of memory exception
 logHeap(this.getClass());
} 
public static void logHeap(Class clazz) {
 Double allocated = new Double(Debug.getNativeHeapAllocatedSize())/new Double((1048576));
 Double available = new Double(Debug.getNativeHeapSize()/1048576.0);
 Double free = new Double(Debug.getNativeHeapFreeSize()/1048576.0);
 DecimalFormat df = new DecimalFormat();
 df.setMaximumFractionDigits(2);
 df.setMinimumFractionDigits(2);
 System.out.println("debug. =================================");
 System.out.println("debug.heap native: allocated " + df.format(allocated) + "MB of " + df.format(available) + "MB (" + df.format(free) + "MB free) in [" + clazz.getName().replaceAll("com.myapp.android.","") + "]");
 System.out.println("debug.memory: allocated: " + df.format(new Double(Runtime.getRuntime().totalMemory()/1048576)) + "MB of " + df.format(new Double(Runtime.getRuntime().maxMemory()/1048576))+ "MB (" + df.format(new Double(Runtime.getRuntime().freeMemory()/1048576)) +"MB free)");
 System.gc();
 System.gc(); 
}

My Code:

@Override

 public View getView(final int position, View convertView, ViewGroup parent) 
 { 
 ViewHolder holder; 
 convertView = null; 
 if (convertView == null) 
 {
 convertView = mInflater.inflate(R.layout.giftcategorieslist, null); 
 holder = new ViewHolder(); 
 holder.imgitem = (ImageView)convertView.findViewById(R.id.imgitem); 
 convertView.setTag(holder);
 } 
 else 
 {
 holder = (ViewHolder) convertView.getTag(); 
 }
 final CategoryData Item = arItems.get(position); 
 strItemrow = Item.toString();
 try 
 {
 if(Item.dwgImage == null)
 {
 if(Item.bImageDownLoaded == 0)
 { 
 holder.progress.setVisibility(View.VISIBLE); 
 DownLoadImageInAThreadHandler(Item, holder); 
 }
 else
 {
 int idNoImage = R.drawable.giftsuggestionsnoimage;
 Drawable dwgImgLoading = GiftCategories.this.getResources().getDrawable(idNoImage);
 holder.imgitem.setImageDrawable(dwgImgLoading);
 holder.imgitem.setVisibility(View.VISIBLE);
 holder.progress.setVisibility(View.GONE); 
 }
 } 
 else
 {
 holder.imgitem.setImageDrawable(Item.dwgImage);
 holder.imgitem.setVisibility(View.VISIBLE); 
 holder.progress.setVisibility(View.GONE);
 }
 }
 catch(Exception e) 
 { 
 System.out.println("Exception in Downloading image : " + e.getMessage());
 } 
 return convertView;
 }
 public void DownLoadImageInAThreadHandler(final CategoryData Item, final ViewHolder holder)
 {
 nImageDownLoads++;
 System.out.println("The images being downloaded :" + nImageDownLoads);
 final Handler handler = new Handler() 
 { 
 @Override public void handleMessage(Message message) 
 { 
 holder.imgitem.setImageDrawable((Drawable) message.obj); 
 holder.imgitem.setVisibility(View.VISIBLE);
 holder.progress.setVisibility(View.GONE);
 }
 };
 //Thread for getting the attributes values
 Thread t = new Thread() 
 {
 public void run()
 { 
 try
 {
 Item.bImageDownLoaded = 2;
 System.out.println("Downloading image : " + Item.ImageUrl);
 InputStream is = fetch(Item.ImageUrl);
 Drawable drawable = Drawable.createFromStream(is, "src"); 
 nImageDownLoads--;
 System.out.println("Downloaded image :" + Item.ImageUrl);
 System.out.println("Remaining images for downloading: " + nImageDownLoads);
 if(drawable != null)
 {
 Item.dwgImage = drawable; 
 Item.bImageDownLoaded = 1;
 //Send the message to the handler
 Message message = handler.obtainMessage(1, drawable); 
 handler.sendMessage(message); 
 }
 else
 {
 int idNoImage = R.drawable.giftsuggestionsnoimage;
 Drawable dwgNoImg = GiftCategories.this.getResources().getDrawable(idNoImage);
 //Send the message to the handler
 Message message = handler.obtainMessage(1, dwgNoImg); 
 handler.sendMessage(message); 
 } 
 }
 catch(Exception exp)
 {
 System.out.println("Exception in DownLoadImageInAThread : " + exp.getMessage());
 }
 } 
 };
 t.start(); 
 }
 private InputStream fetch(String urlString) throws MalformedURLException, IOException 
 { 
 DefaultHttpClient httpClient = new DefaultHttpClient();
 HttpGet request = new HttpGet(urlString);
 HttpResponse response = httpClient.execute(request);
 return response.getEntity().getContent();
 } 
 class ViewHolder 
 { 
 ImageView imgitem; 
 }
 }

}

thanks

asked Sep 2, 2011 at 10:43
2
  • 3
    What's the image size and how did you use it in activity please show that code. Commented Sep 2, 2011 at 11:01
  • Code is added please refer the question. Commented Sep 2, 2011 at 11:14

2 Answers 2

8

You are saving all the images in the heap!

Probably if you do not scroll down you will not get the out of memory error

Try to

  • save the images to file when downloaded
  • let your Item objects hold the path of the image and not the whole Drawable

CODE

This is a function I created that will take a url from you and it will return a drawable! It will save it to a file and get it if it exists

If not, it will download it and return the drawable.

In this case, all you have to do is save the url in Item and give it to this function when drawable is needed.

/**
 * Pass in an image url to get a drawable object
 * 
 * @return a drawable object
 */
 private static Drawable getDrawableFromUrl(final String url) {
 String filename = url;
 filename = filename.replace("/", "+");
 filename = filename.replace(":", "+");
 filename = filename.replace("~", "s");
 final File file = new File(Environment.getExternalStorageDirectory()
 + File.separator + filename);
 boolean exists = file.exists();
 if (!exists) {
 try {
 URL myFileUrl = new URL(url);
 HttpURLConnection conn = (HttpURLConnection) myFileUrl
 .openConnection();
 conn.setDoInput(true);
 conn.connect();
 InputStream is = conn.getInputStream();
 final Bitmap result = BitmapFactory.decodeStream(is);
 is.close();
 new Thread() {
 public void run() {
 ByteArrayOutputStream bytes = new ByteArrayOutputStream();
 result.compress(Bitmap.CompressFormat.JPEG, 40, bytes);
 try {
 if (file.createNewFile()){
 //
 }
 else{
 //
 }
 FileOutputStream fo;
 fo = new FileOutputStream(file);
 fo.write(bytes.toByteArray());
 fo.flush();
 fo.close();
 } catch (IOException e) {
 e.printStackTrace();
 }
 }
 }.start();
 BitmapDrawable returnResult = new BitmapDrawable(result);
 return returnResult;
 } catch (FileNotFoundException e) {
 e.printStackTrace();
 } catch (MalformedURLException e) {
 e.printStackTrace();
 } catch (IOException e) {
 e.printStackTrace();
 }
 return null;
 }
 else {
 return new BitmapDrawable(BitmapFactory.decodeFile(file.toString()));
 }
 }
answered Sep 2, 2011 at 11:20
Sign up to request clarification or add additional context in comments.

10 Comments

It is not a choice. You can not save them in the heap. You either save them in file and delete them onDestroy of your app, or save them always in file.
In your Thread t = new Thread() get the image using getDrawableFromUrl(final String url) and work the same way
one more thing how to say that image are stored in the heap memory in my code.
because every CategoryData has bitmap in it!... let it only have a string (url) (:
Then where the images are stored?
|
0

You could try to run a garbage collection(system.gc()) before you start this process. While it may work, this is not the best solution as gc will not always run just because you call it. Normally if you have to call gc in your program it means your doing something wrong. I would try to move the images to the file system as suggested above.

answered Sep 2, 2011 at 11:32

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.