如何避免内存溢出异常

4
在我的应用程序中,我使用图像的URL从网络下载图像。我有很多图片,所以我为此实现了分页技术,并且在竖直方向上每个页面显示15张图片。在这种情况下,当我滚动页面查看图片时,我的应用程序崩溃并出现内存不足异常。请问有人可以帮助我吗?
日志记录:
02-07 11:23:52.256: ERROR/ACRA(7236): El Gifto fatal error : bitmap size exceeds VM budget(Heap Size=7943KB, Allocated=3485KB, Bitmap Size=12546KB)    
02-07 11:23:52.256: ERROR/ACRA(7236): java.lang.OutOfMemoryError: bitmap size exceeds VM budget(Heap Size=7943KB, Allocated=3485KB, Bitmap Size=12546KB)    
02-07 11:23:52.256: ERROR/ACRA(7236):  at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)    
02-07 11:23:52.256: ERROR/ACRA(7236):  at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:690)    
02-07 11:23:52.256: ERROR/ACRA(7236):  at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:490)    
02-07 11:23:52.256: ERROR/ACRA(7236):  at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697)    
02-07 11:23:52.256: ERROR/ACRA(7236):  at android.graphics.drawable.Drawable.createFromStream(Drawable.java:657)    
02-07 11:23:52.256: ERROR/ACRA(7236):  at com.ibkr.elgifto.GiftCategories$itemlistadapter$3.getDrawableFromUrl(GiftCategories.java:837)    
02-07 11:23:52.256: ERROR/ACRA(7236):  at com.ibkr.elgifto.GiftCategories$itemlistadapter$3.run(GiftCategories.java:724)

这是我的代码:

public void DownLoadImageInAThreadHandler(final CategoryData Item, final ViewHolder holder)
{   
    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
            {                                       
                drawable = getDrawableFromUrl(Item.ImageUrl);                                                       

                if(drawable != null)
                {                                                               
                    //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());
            }
        }

        private Drawable getDrawableFromUrl(String imageUrl) throws IOException
        {                   
            Drawable image = null;

            try 
            {
                InputStream in = (java.io.InputStream) new java.net.URL(imageUrl).getContent();
                if (in != null)
                {
                    image = Drawable.createFromStream(in, "image");
                    in.close();
                }
            } 
            catch (Exception ex) 
            {
                ex.printStackTrace();
            }
            return image;
        }                                                               
    };
    t.start();                                              
}

这是在模拟器上还是真实设备上发生的? - Zacharias Manuel
在两种情况下(设备和模拟器)。 - naresh
不知道确切的原因。我通过给出system.gc();来解决了这个问题。但这并不是确切的方法。 - Zacharias Manuel
我应该在哪里调用gc()方法? - naresh
3个回答

0

如果您遇到内存问题,则有两个选择: 第一。=>使用位图解码图像 或第二 =>下载图像并将其保存在临时文件夹中,然后使用它。不需要时,请从文件夹中删除所有文件。

有关下载图像并将其保存在文件夹中,请参见此链接

有关解码,请参见来自stackoverflow的此链接。 也许这会帮助您。 谢谢


0

我想你的意思是调用Bitmap.recycle方法。是的,你必须跟踪你的位图并记得正确地处理它们,你不能像处理Java对象一样随意丢弃它们。 - Lawrence D'Oliveiro

0
这是一个常见的问题,我认为你应该为你的位图使用一组SoftReference。查看文档和在线资源以了解SoftReference:它将允许Android在需要时清除位图占用的空间。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接