2011-10-12 35 views
9

tôi đang hiển thị hình ảnh trong listview và nhận ra lỗi bộ nhớ bất kỳ một hướng dẫn cho tôi giải pháp cho vấn đề này ở đây là những gì là mã của tôiOut Of Lỗi bộ nhớ với những hình ảnh

LogCat

ERROR/AndroidRuntime(1010): java.lang.OutOfMemoryError: bitmap size exceeds VM budget 
ERROR/AndroidRuntime(1010):  at android.graphics.BitmapFactory.nativeDecodeByteArray(Native Method) 
ERROR/AndroidRuntime(1010):  at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:405) 
ERROR/AndroidRuntime(1010):  at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:418) 
ERROR/AndroidRuntime(1010):  at com.Adapters.AdapterTours.getView(AdapterTours.java:73) 
ERROR/AndroidRuntime(1010):  at android.widget.AbsListView.obtainView(AbsListView.java:1409) 
ERROR/AndroidRuntime(1010):  at android.widget.ListView.makeAndAddView(ListView.java:1745) 
ERROR/AndroidRuntime(1010):  at android.widget.ListView.fillUp(ListView.java:700) 
ERROR/AndroidRuntime(1010):  at android.widget.ListView.fillGap(ListView.java:646) 
ERROR/AndroidRuntime(1010):  at android.widget.AbsListView.trackMotionScroll(AbsListView.java:3399) 
ERROR/AndroidRuntime(1010):  at android.widget.AbsListView.onTouchEvent(AbsListView.java:2233) 
ERROR/AndroidRuntime(1010):  at android.widget.ListView.onTouchEvent(ListView.java:3446) 
ERROR/AndroidRuntime(1010):  at android.view.View.dispatchTouchEvent(View.java:3885) 
ERROR/AndroidRuntime(1010):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:903) 
ERROR/AndroidRuntime(1010):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942) 
ERROR/AndroidRuntime(1010):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942) 
ERROR/AndroidRuntime(1010):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942) 
ERROR/AndroidRuntime(1010):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942) 
ERROR/AndroidRuntime(1010):  at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1691) 
ERROR/AndroidRuntime(1010):  at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1125) 
ERROR/AndroidRuntime(1010):  at android.app.Activity.dispatchTouchEvent(Activity.java:2096) 
ERROR/AndroidRuntime(1010):  at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1675) 
ERROR/AndroidRuntime(1010):  at android.view.ViewRoot.deliverPointerEvent(ViewRoot.java:2194) 
ERROR/AndroidRuntime(1010):  at android.view.ViewRoot.handleMessage(ViewRoot.java:1878) 
ERROR/AndroidRuntime(1010):  at android.os.Handler.dispatchMessage(Handler.java:99) 
ERROR/AndroidRuntime(1010):  at android.os.Looper.loop(Looper.java:130) 
ERROR/AndroidRuntime(1010):  at android.app.ActivityThread.main(ActivityThread.java:3683) 
ERROR/AndroidRuntime(1010):  at java.lang.reflect.Method.invokeNative(Native Method) 
ERROR/AndroidRuntime(1010):  at java.lang.reflect.Method.invoke(Method.java:507) 
ERROR/AndroidRuntime(1010):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 
ERROR/AndroidRuntime(1010):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 
ERROR/AndroidRuntime(1010):  at dalvik.system.NativeStart.main(Native Method) 

GetView Phương pháp

public View getView(final int position, View convertView, ViewGroup parent) { 

     ViewHolder holder; 

     if (convertView == null) { 
     convertView = mInflater.inflate(R.layout.list_tours, null); 
     holder = new ViewHolder(); 
     holder.tourTitle = (TextView) convertView.findViewById(R.id.tourTitle); 
     holder.tourIcon = (ImageView) convertView.findViewById(R.id.tourIcon); 
     holder.tourDetail = (TextView) convertView.findViewById(R.id.tourDetail); 
     convertView.setTag(holder); 

     } else { 
     holder = (ViewHolder) convertView.getTag(); 
     } 


     DalTours tour = getItem(position); 

     String tempTag = String.valueOf(tour.getId()); 
     holder.tourIcon.setTag(tempTag); 

     if(tour.getImageByteArray() != null) 
     { 
      Bitmap image = BitmapFactory.decodeByteArray(tour.getImageByteArray(), 0, tour.getImageByteArray().length); 
      holder.tourIcon.setImageDrawable(getScaledImage(image)); 
      image = null; 

     }else 
     { 


      holder.tourIcon.setTag(tour); 
      Bitmap cachedImage = ImageLoader.loadBitmap(tour,new ImageLoader.ImageCallback() { 

       @Override 
       public void imageLoaded(Bitmap imageBitmap, DalTours tour) { 
        ImageView image = (ImageView)listview.findViewWithTag(tour); 
        if(image != null) 
         { 

         try 
         { 
          ByteArrayOutputStream stream = new ByteArrayOutputStream(); 
          if(imageBitmap != null) 
          { 


           image.setImageDrawable(getScaledImage(imageBitmap)); 
           imageBitmap.compress(CompressFormat.PNG, 0 ,stream); 
           byte[] bitmapdata = stream.toByteArray(); 
           tours.get(position).setImageByteArray(bitmapdata); 


         } 
          stream = null; 
         }finally 
         { 

         } 
         } 

       } 
      }); 
       holder.tourIcon.setImageDrawable(getScaledImage(cachedImage)); 

     } 

     holder.tourTitle.setText(tours.get(position).getTitle()); 
     holder.tourDetail.setText(tours.get(position).getDetail()); 

     return convertView; 
    } 

Scale hình ảnh Chức năng

public Drawable getScaledImage(Bitmap actualBitmap) 
    { 
     BitmapDrawable bmd= null; 
     if(actualBitmap != null) 
     { 

      int width = actualBitmap.getWidth(); 
      int height = actualBitmap.getHeight(); 

      Activity parent = (Activity)context; 
      Display display = parent.getWindowManager().getDefaultDisplay(); 
      int Screenwidth = display.getWidth(); 
      int Screenheight = display.getHeight(); 


     float newWidth = (Screenwidth*35)/100; 

     float temp = newWidth/width; 
     float newHeight = temp * height; 



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

     Matrix matrix = new Matrix(); 

     matrix.postScale(scaleWidth, scaleHeight); 
     Bitmap resizedBitmap = Bitmap.createBitmap(actualBitmap, 0, 0, 
          width, height, matrix, true); 

     bmd = new BitmapDrawable(resizedBitmap); 
     } 
     return bmd; 

    } 

ảnh Loader Lớp

public class ImageLoader { 
    private static HashMap<String, SoftReference<Bitmap>> imageCache; 

    public ImageLoader() { 
     //imageCache = new HashMap<String, SoftReference<Bitmap>>(); 
    } 

    public static Bitmap loadBitmap(final DalTours tour, final ImageCallback imageCallback) { 
     if(imageCache == null) 
      imageCache = new HashMap<String, SoftReference<Bitmap>>(); 

     if (imageCache.containsKey(tour.getImageurl())) { 
      SoftReference<Bitmap> softReference = imageCache.get(tour.getImageurl()); 
      Bitmap Bitmap = softReference.get(); 
      if (Bitmap != null) { 
       return Bitmap; 
      } 
     } 
     final Handler handler = new Handler() { 
      @Override 
      public void handleMessage(Message message) { 
       imageCallback.imageLoaded((Bitmap) message.obj, tour); 
      } 
     }; 
     new Thread() { 
      @Override 
      public void run() { 
       Bitmap Bitmap = loadImageFromUrl(tour.getImageurl()); 
       imageCache.put(tour.getImageurl(), new SoftReference<Bitmap>(Bitmap)); 
       Message message = handler.obtainMessage(0, Bitmap); 
       handler.sendMessage(message); 
      } 
     }.start(); 
     return null; 
    } 

    public static Bitmap loadImageFromUrl(String url) { 

     Bitmap bm; 
     try { 

       URL aURL = new URL(url); 
       URLConnection conn = aURL.openConnection(); 

       conn.connect(); 
       InputStream is = null; 
       try 
       { 
       is= conn.getInputStream(); 
       }catch(IOException e) 
       { 
        return null; 
       } 

       BufferedInputStream bis = new BufferedInputStream(is); 

       bm = BitmapFactory.decodeStream(bis); 
       bis.close(); 
       is.close(); 

      } catch (IOException e) { 
      return null; 
      } 

      return bm; 


    } 

    public interface ImageCallback { 
     public void imageLoaded(Bitmap imageBitmap, DalTours tour); 
    } 
} 

bất kỳ trợ giúp sẽ được apprecicated

+1

hình ảnh tôi đang sử dụng là rất lớn – UMAR

+0

Đây có phải là mã của Fedor của Lazy Loading hình ảnh? http://stackoverflow.com/questions/541966/android-how-do-i-do-a-lazy-load-of-images-in-listview/3068012#3068012 –

+0

http: //chrysler-contents.g1curator. com/1313185770.jpg – UMAR

Trả lời

6

cuối cùng tôi giải quyết giải quyết vấn đề hình ảnh cao này nhưng lại gây ra lỗi bộ nhớ sử dụng chủ đề sau Large Image Manipulation

và đây là mã của tôi để tải về và mở rộng quy mô hình ảnh theo kích thước yêu cầu của bạn.

không cần thêm chức năng mở rộng tùy chỉnh !!!

public static Bitmap loadImageFromUrl(String url) { 

     Bitmap bm; 
     try { 

       URL aURL = new URL(url); 
       URLConnection conn = aURL.openConnection(); 

       conn.connect(); 
       InputStream is = null; 
       try 
       { 
       is= conn.getInputStream(); 
       }catch(IOException e) 
       { 
        return null; 
       } 

       BufferedInputStream bis = new BufferedInputStream(is); 

       bm = BitmapFactory.decodeStream(bis); 

       bis.close(); 
       is.close(); 

      } catch (IOException e) { 
      return null; 
      } 

     return Bitmap.createScaledBitmap(bm,100,100,true); 


    } 
3

bạn phải recycle bitmap. Việc thực hiện bitmap là bản địa, vì vậy đối tượng java là nhỏ và một ứng cử viên nghèo cho bộ sưu tập rác java nhưng bộ nhớ vẫn được cấp phát. Taka một cái nhìn để Bitmap.recycle()

+0

bạn có thể cho tôi bất kỳ ví dụ nào sử dụng mã này trong mã của tôi :( – UMAR

+0

okey ... để bắt đầu .. quy tắc của ngón tay cái: Mỗi khi bạn không cần đối tượng bitmap, hãy gọi Bitmap.recycle. Trong mã của bạn: trong getScaledImage sau bạn tạo bmd, resizedBitmap và actualBitmap không còn cần thiết nữa .. hãy gọi resizedBitmap.recycle() và actualBitmap.recycle() Sử dụng softreference để lấy bộ nhớ cache bitmap bộ nhớ imo không phải là một ý tưởng hay (đối với việc thực hiện bitmap gốc) – Blackbelt

-1

Đây chắc chắn là trường hợp có bitmap cho hình ảnh lớn trong bộ nhớ. Nếu bạn liên tục thực hiện thao tác này thì tốt nhất là nên tái chế bitmap mỗi lần. Tuy nhiên, chỉ tái chế không đảm bảo rằng bộ nhớ được giải phóng, nó hầu như không được đánh dấu để thu gom rác thải. Vì vậy, như là một bước bổ sung, bạn nên chăm sóc bộ sưu tập rác quá.

Sử dụng mã này;

Bitmap mybitmap = ....; // you are getting the bitmap here 
mybitmap.recycle(); 
System.gc(); // the above recycling may not be enough always 
+0

Hệ thống gọi .gc() không phải là một ý kiến ​​hay. Hãy đọc chúng: http://stackoverflow.com/questions/2414105/why-is-it-bad-practice-to-call- system-gc –

24

Đối với Giải quyết java.lang.OutOfMemoryError ngoại lệ tại android.graphics.BitmapFactory.nativeDecodeByteArray, bạn nên sử dụng đoạn mã sau:

BitmapFactory.Options options=new BitmapFactory.Options();// Create object of bitmapfactory's option method for further option use 
       options.inPurgeable = true; // inPurgeable is used to free up memory while required 
       Bitmap songImage1 = BitmapFactory.decodeByteArray(thumbnail,0, thumbnail.length,options);//Decode image, "thumbnail" is the object of image file 
       Bitmap songImage = Bitmap.createScaledBitmap(songImage1, 50 , 50 , true);// convert decoded bitmap into well scalled Bitmap format. 

imageview.SetImageDrawable(songImage); 
+1

Câu trả lời tuyệt vời !!!! Nó thực sự đã giúp tôi rất nhiều :) .. – GOLDEE

+2

'inPurgeable' là không được chấp nhận có vẻ như cho các phiên bản mới hơn. –

+0

Cảm ơn bạn rất nhiều. mã này làm việc cho tôi. – Vrajesh

Các vấn đề liên quan