2011-03-21 22 views
7

Entiendo que esta pregunta se realiza pocas veces. Ninguno de ellos tiene clara la solución. Déjame explicarte el problema.Error de outofmemory de Android excede el presupuesto de vm en 2.3.3

  1. Tengo una actividad que carga 4 imágenes a la vez.
  2. Cardo las imágenes en el método onResume().
  3. La actividad arroja un error de mapa de bits al cargar.

Notas.

  1. Estoy configurando la imagen utilizando la llamada al método setImageResource (R.drawable.xxxx) y no directamente a los mapas de bits/dibujables.
  2. Las imágenes están escaladas correctamente.
  3. La actividad FUNCIONA FINA en todos los emuladores anteriores a 2.3 y FUNCIONA FINA en el dispositivo real (Samsung Galaxy 5)
  4. El error aparece en la primera inicialización y no se activa ningún evento de cambio de orientación.
  5. las imágenes tienen una escala de 800 x 600 y promedian 15 kb (cada uno) de tamaño.

Deseo cualquier solución. También avíseme si tiene problemas similares con el emulador de Android 2.3.3.

[Actualización] -snippets

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
      ... 
    img_topLeft = (ImageView) findViewById(R.id.Img_Alph_Q_TopLeft); 
    img_topRight = (ImageView) findViewById(R.id.Img_Alph_Q_TopRight); 
    img_bottomLeft = (ImageView) findViewById(R.id.Img_Alph_Q_BottomLeft); 
    img_bottomRight = (ImageView) findViewById(R.id.Img_Alph_Q_BottomRight); 
    ... 
    } 
protected void onResume() { 
    super.onResume(); 
      img_topLeft.setImageResource(R.drawable.xxx); 
      img_topRight.setImageResource(R.drawable.xxx); 
      img_bottomLeft.setImageResource(R.drawable.xxx); 
      img_bottomRight.setImageResource(R.drawable.xxx); 
    ... 
    } 

03-21 08:59:17.362: ERROR/dalvikvm-heap(5883): 4320000-byte external allocation too large for this process. 03-21 08:59:17.412: ERROR/GraphicsJNI(5883): VM won't let us allocate 4320000 bytes 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): FATAL EXCEPTION: main 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): java.lang.OutOfMemoryError: bitmap size exceeds VM budget 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.graphics.Bitmap.nativeCreate(Native Method) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.graphics.Bitmap.createBitmap(Bitmap.java:477) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.graphics.Bitmap.createBitmap(Bitmap.java:444) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:349) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.graphics.BitmapFactory.finishDecode(BitmapFactory.java:498) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:473) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:336) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.content.res.Resources.loadDrawable(Resources.java:1709) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.content.res.Resources.getDrawable(Resources.java:581) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.widget.ImageView.resolveUri(ImageView.java:501) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.widget.ImageView.setImageResource(ImageView.java:280) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at Quiz.java:124) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): Quiz.onResume(Quiz.java:92) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1150) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.app.Activity.performResume(Activity.java:3832) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2110) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2135) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1668) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.app.ActivityThread.access$1500(ActivityThread.java:117) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.os.Handler.dispatchMessage(Handler.java:99) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.os.Looper.loop(Looper.java:123) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.app.ActivityThread.main(ActivityThread.java:3683) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at java.lang.reflect.Method.invokeNative(Native Method) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at java.lang.reflect.Method.invoke(Method.java:507) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at dalvik.system.NativeStart.main(Native Method)

Gracias. Se las arregló para resolverlo. Compartir el código para beneficio de otros Clase personalizada que resolvió este problema. basado en el enlace @ Janardhanan.S.

public class BitmapResizer { 

public static Bitmap decodeImage(Resources res, int id ,int requiredSize){ 
    try { 
     BitmapFactory.Options o = new BitmapFactory.Options(); 
     o.inJustDecodeBounds = true; 
     BitmapFactory.decodeResource(res, id, o); 

     //Find the correct scale value. It should be the power of 2. 
     final int REQUIRED_SIZE=requiredSize; 
     int width_tmp=o.outWidth, height_tmp=o.outHeight; 
     int scale=1; 
     while(true){ 
      if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE) 
       break; 
      width_tmp/=2; 
      height_tmp/=2; 
      scale*=2; 
     } 

     //decode with inSampleSize 
     BitmapFactory.Options o2 = new BitmapFactory.Options(); 
     o2.inSampleSize=scale; 
     return BitmapFactory.decodeResource(res, id, o2); 
    } catch (Exception e) { 

    } 
    return null; 
} 

} 

//Class call 
int requiredsize = 100; // Still playing around with this number to find the optimum value 
img_topLeft.setImageBitmap(BitmapResizer.decodeImage(getResources(), 
     AlphResourceSet.R.drawable.xxx, requiredsize)); 
+0

publicar su código onResume, y podría ser más fácil para ayudarle. –

Respuesta

3

El mapa de bits consume una gran cantidad de espacio en la memoria. No cree una nueva variable de mapa de bits para todas las imágenes que cargue en la actividad, en su lugar, puede crear una variable de mapa de bits y volver a utilizarlas tanto como sea posible.

se puede utilizar este fragmento para cambiar el tamaño de mapa de bits

http://pastebin.com/D8vbQd2u

+0

¿Tengo que manejar esto teniendo en cuenta que no estoy usando una variable de mapa de bits? Uso el formulario de referencia dibujable directamente. código adjunto – GSree

+0

no es necesario que considere cambiar el tamaño de las imágenes pequeñas, pero 64 KB en una sola actividad afectará a la IU y consumirá memoria. convertirlos a mapa de bits y alimentarlos a la vista de imagen – Jana

+0

rdhanan.S ¿Qué es 64kb? ¿Hay un tamaño de imagen por actividad? Mis imágenes tienen ~ 15kb de tamaño en formato png. Una actividad tendrá 4 imágenes. Entonces ~ 15 x 4 = ~ 60Kb. – GSree

0

Se puede publicar un fragmento de código de la Actividad + StackTrace.

¿Ya ha consultado el Avoiding memory leaks article?

Especialmente la parte siguiente:

Cuando un Disponibles está unido a un punto de vista, la vista se fija como una devolución de llamada en el dibujable. En el fragmento de código anterior, esto significa que el dibujable tiene una referencia al TextView que tiene una referencia a la actividad (el Contexto) que a su vez tiene referencias a casi cualquier cosa (dependiendo de su código)

+0

Revisé el enlace. No estoy seguro de si hay mucho que pueda hacer con mi código. Actualizado el fragmento de código a la pregunta. Por favor revise y dígame si necesito hacer alguna modificación en base a esto. Las imágenes – GSree

0

It parece que las imágenes son muy pesadas en naturaleza. Recomiendo iniciar el AsyncTimer que realmente devuelve la instancia de mapa de bits y en doBackground() de AsyncTask pasar el ID de la imagen y reescalarlo para desear el tamaño, por ejemplo 32 x 32 usando el método createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter) de la clase Bitmap.

+0

tienen una escala de 800 x 600 y un tamaño promedio de 15 kb (cada una). ¿Podría publicar algún fragmento sobre cómo hacer AsyncTimer? – GSree

Cuestiones relacionadas