android - out of memory

一世执手 提交于 2019-12-24 02:24:05

问题


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


回答1:


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()));
        }
    }



回答2:


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.



来源:https://stackoverflow.com/questions/7282334/android-out-of-memory

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!