2011-10-12 14 views
9

estoy mostrando imágenes en vista de lista y salir de error de memoria me guíe cualquiera lo que es la solución a este problema aquí es mi códigoerror de memoria con imágenes

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 Método

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

Función Escala imagen

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; 

    } 

imagen cargador de clases

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

cualquier ayuda sería apprecicated

+1

imagen que estoy utilizando es muy grande – UMAR

+0

Es este el código de Fedor Lazy Loading images? 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

Respuesta

6

finalmente a resolver este problema de imagen de alta resolución en la que estaba causando error de falta de memoria utilizando hilo siguiente Large Image Manipulation

y aquí está mi código para la descarga y escalado de imagen de acuerdo a su tamaño requerido.

¡ya no se requiere una función de escalado personalizada!

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

tienes que recycle mapa de bits. La implementación del mapa de bits es nativa, por lo que el objeto java es pequeño y poco apto para la recolección de basura de Java, pero la memoria aún está asignada. Taka un vistazo a Bitmap.recycle()

+0

puede Dame algún ejemplo donde usar esto en mi código :( – UMAR

+0

okey ... para empezar .. regla de oro: cada vez que no necesites el objeto de mapa de bits, llama a Bitmap.recycle. En tu código: en getScaledImage después de ti crear bmd, resizedBitmap y actualBitmap ya no son necesarios ... así que llame a resizedBitmap.recycle() y actualBitmap.recycle(). Use softreference para obtener un caché de mapa de bits de memoria. imo no es una buena idea (para la implementación del mapa de bits nativo) – Blackbelt

-1

Definitivamente es un caso de tener un mapa de bits para una imagen grande en la memoria. Si realiza esta operación repetidamente, es bueno reciclar el mapa de bits cada vez. Sin embargo, solo reciclar no garantiza que la memoria se libere, apenas está marcada para la recolección de basura. Por lo tanto, como paso adicional, también debe ocuparse de la recolección de basura.

Utilice este código;

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

Sistema de llamadas .gc() no es una buena idea. Lea ésos: http://stackoverflow.com/questions/2414105/why-is-it-bad-practice-to-call- system-gc –

24

para resolver java.lang.OutOfMemoryError Excepción en android.graphics.BitmapFactory.nativeDecodeByteArray, se debe utilizar siguiente código:

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

¡¡¡Gran respuesta !!!! Realmente me ayudó mucho :) .. – GOLDEE

+2

'inPurgeable' está en desuso parece que para las versiones más nuevas. –

+0

Muchas gracias. este código me funciona – Vrajesh

Cuestiones relacionadas