Causado por: java.lang.OutOfMemoryError: el tamaño del bitmap excede el presupuesto de VM

En mi aplicación, cuando bash abrirlo, forzo cerrado y el error apunta a la línea “setContentView (R.layout.Menu);” del diseño. Y en el archivo XML, muestra la vista de imagen “OutOfMemoryError” en mi diseño. Estoy realmente confundido. Por favor, guíame para un paso más.

Editado:

Mi aplicación utiliza una base de datos y, por primera vez, analiza algunos datos XML e inserta en la base de datos Sqlite. Mi problema de Outofmemory ocurre solo la primera vez. La segunda vez funciona bien. Intenté System.gc (). ¿Hay algún problema con eso?

Este es mi Log:

E/dalvikvm-heap(2712): 105376-byte external allocation too large for this process. VM won't let us allocate 105376 bytes FATAL EXCEPTION: main java.lang.RuntimeException: Unable to start activity ComponentInfo{com.Test/com.Test.Menu}: android.view.InflateException: Binary XML file line #13: Error inflating class  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663) at android.app.ActivityThread.access$1500(ActivityThread.java:117) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:130) at android.app.ActivityThread.main(ActivityThread.java:3683) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:507) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) at dalvik.system.NativeStart.main(Native Method) Caused by: android.view.InflateException: Binary XML file line #13: Error inflating class  at android.view.LayoutInflater.createView(LayoutInflater.java:518) at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56) at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:568) at android.view.LayoutInflater.rInflate(LayoutInflater.java:623) at android.view.LayoutInflater.rInflate(LayoutInflater.java:626) at android.view.LayoutInflater.inflate(LayoutInflater.java:408) at android.view.LayoutInflater.inflate(LayoutInflater.java:320) at android.view.LayoutInflater.inflate(LayoutInflater.java:276) at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:207) at android.app.Activity.setContentView(Activity.java:1657) at com.Test.Menu.onCreate(Menu.java:32) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611) ... 11 more Caused by: java.lang.reflect.InvocationTargetException at java.lang.reflect.Constructor.constructNative(Native Method) at java.lang.reflect.Constructor.newInstance(Constructor.java:415) at android.view.LayoutInflater.createView(LayoutInflater.java:505) ... 23 more Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method) at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:460) at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:336) at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697) at android.content.res.Resources.loadDrawable(Resources.java:1709) at android.content.res.TypedArray.getDrawable(TypedArray.java:601) at android.widget.ImageView.(ImageView.java:118) at android.widget.ImageView.(ImageView.java:108) 

Este es mi código XML:

    

Supongo que el problema no está en tu diseño; el problema está en otro lugar en tu código. Y probablemente estés perdiendo contexto en alguna parte .

Otra razón probable es que debe crear objetos múltiples voluminosos al analizar su XML (como mencionó, esto ocurre la primera vez cuando analiza XML). Aunque Java tiene un enfoque de recolección automática de basura, pero aún así no se puede confiar plenamente en él. Es una buena práctica anular la instancia de su colección o borrar el contenido de sus objetos cuando ya no los necesite.

Pero igual he preparado una lista de puntos importantes que debes recordar al tratar con bitmaps en Android.

1) Puede llamar a reciclar en cada bitmap y establecerlos como nulos. ( bitmap.recycle() liberará toda la memoria utilizada por este bitmap, pero no anula el objeto de bitmap).

2) También puede desvincular los drawables asociados con los diseños cuando se destruye una actividad. Pruebe el código que se proporciona a continuación y también eche un vistazo a este enlace .

  private void unbindDrawables(View view) { if (view.getBackground() != null) { view.getBackground().setCallback(null); } if (view instanceof ViewGroup) { for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) { unbindDrawables(((ViewGroup) view).getChildAt(i)); } ((ViewGroup) view).removeAllViews(); } } // Call this method from onDestroy() void onDestroy() { super.onDestroy(); unbindDrawables(findViewById(R.id.RootView)); System.gc(); } 

3) Puede convertir sus hashmaps en WeakHashmaps , de modo que su memoria se libere cuando el sistema tenga poca memoria.

4) Puede escalar / cambiar el tamaño de todos sus mapas de bits. Para escalar bitmaps puedes probar algo como esto:

  BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 8; Bitmap preview_bitmap=BitmapFactory.decodeStream(is, null, options); 

Esta opción inSampleSize reduce el consumo de memoria.

Aquí hay un método completo. Primero lee el tamaño de la imagen sin decodificar el contenido en sí. Luego encuentra el mejor valor en el Tamaño de Muestra; debería ser un poder de 2. Y finalmente la imagen se decodifica.

 // Decodes image and scales it to reduce memory consumption private Bitmap decodeFile(File f){ try { // Decode image size BitmapFactory.Options o = new BitmapFactory.Options(); o.inJustDecodeBounds = true; BitmapFactory.decodeStream(new FileInputStream(f),null,o); // The new size we want to scale to final int REQUIRED_SIZE=70; // Find the correct scale value. It should be the power of 2. int scale=1; while(o.outWidth/scale/2 >= REQUIRED_SIZE && o.outHeight/scale/2 >= REQUIRED_SIZE) scale*=2; // Decode with inSampleSize BitmapFactory.Options o2 = new BitmapFactory.Options(); o2.inSampleSize=scale; return BitmapFactory.decodeStream(new FileInputStream(f), null, o2); } catch (FileNotFoundException e) { } return null; } 

Eche un vistazo a este enlace. .

5) Puede anular el método onLowMemory() en una actividad que recibe una llamada cuando todo el sistema tiene poca memoria. Puede liberar algunos recursos allí.

6) Puede hacer que sus objetos SoftReference o Weakreference se liberen en condiciones de poca memoria.

Una fuga de memoria muy común que observé se debe a la implementación de clases internas y la implementación de Handler en la Activity . Este enlace habla sobre el mismo en más detalle .

Espero que esto ayude a eliminar tu problema.

Este es un problema típico cuando se usa ImageView de Android con imágenes grandes en dispositivos más antiguos (incluso si el tamaño del archivo es solo de varios kilobytes). La biblioteca de gráficos nativa llamada skia que se utiliza para decodificar la imagen asigna memoria nativa en función de las dimensiones de la imagen, por lo que el tamaño del archivo no influye en esto directamente.

Incluso si omite el src -attribute en la definición de diseño XML para cargar la imagen usted mismo en su método onCreate() , se desencadenará el mismo error. La única forma de evitar esto es utilizar un inSampleSize en BitmapFactory.decodeStream para realizar una reducción de muestreo directamente durante la deencoding (consulte Extraño problema de BitmapFactory.decodeStream de memoria al cargar una imagen en un objeto Bitmap, por ejemplo). Esto mismo plantea la pregunta de cómo determinar este factor de escala.

La mejor solución que encontré al manejar imágenes grandes es reemplazar el ImageView con un WebView y cargar algo de HTML mínimo como este:

 webView.loadUrl("file:///android_res/raw/background.html"); 

donde el contenido de raw/background.html podría ser algo como esto:

 < !DOCTYPE html>          

El motor WebKit que se utiliza en WebView realiza la carga de imágenes de una manera mucho más eficiente, por lo que esos errores de asignación de memoria deberían desaparecer.

Incluso puede usar diferentes imágenes para retrato y paisaje poniéndolas en drawable-port y drawable-land . Pero luego debe llamar a clearCache(false) en la instancia de WebView en su método onDestroy() porque de lo contrario siempre se usará la imagen almacenada en la primera carga (la desactivación del almacenamiento en caché en la instancia de WebView no funciona).

Muchos dispositivos tienen memoria limitada y limitada disponible para cada dispositivo. Muchos dispositivos antiguos asignan 16 MB de memoria a su aplicación, mientras que algunos dispositivos más modernos pueden asignar 24 MB o incluso 32 MB (he visto un dispositivo con solo 14 MB).

Cada vez que cargue tantas imágenes en la memoria, este espacio se llena muy rápidamente, lo que provoca que se genere OutOfMemoryError. Para superar este problema, debe (como han dicho las respuestas anteriores) reducir las imágenes a miniaturas y solo mantener las miniaturas en la memoria del dispositivo (memoria reducida) y guardar las imágenes en SDCARD.

Puede ver cuánta memoria está usando su progtwig desde el diseño de DDMS en Eclipse. Creo que también puede anular la clase de Aplicación para escuchar la función de advertencia “Memoria baja”.

Cuando lea en el Bitmap a través de BitmapFactory, establezca el parámetro BitmapFactory.Option inScaled en 2 o 4 (o lo que sea que le funcione) para crear una imagen más pequeña y con menos memoria.

En general, solo hay una solución: use imágenes más pequeñas. Si no hay código, es difícil decir qué es exactamente lo que está mal. Puede intentar reducir el tamaño de la imagen.

Además de lo que la gente ha escrito aquí, sugiero ver este video de Google, que señala algunos problemas comunes de memoria y cómo encontrar la causa de su problema de memoria:

Gestión de memoria para aplicaciones de Android

Tuve el mismo problema antes y estaba depurando en S4 Android 4.3. La solución fue: copiar las imágenes de la carpeta mdpi a la carpeta hdpi (para que estén ahora en ambas carpetas)

¡Sé extraño! pero esto resolvió mi problema.

Después de pasar mucho tiempo con este problema, ¡encontré la solución! Todo lo que necesitas hacer es pedir más memoria. Coloque este código dentro de su manifiesto de Android en:

 : 

Poner:

 android:largeHeap="true" 

¡Funcionó muy bien para mí! Tenga en cuenta que esta solución solo funciona en API 11 y superior.

Más información aquí.

Se ve como tu imagen es de gran tamaño para que puedas decodificar tu imagen y usar android: largeHeap = “verdadero”. dentro de manifiesto de etiqueta de aplicación

Es posible que haya pasado por todas las soluciones anteriores, pero aún así pruébelo. Estaba perdido en encontrar una solución hasta que lo obtuve. Esto podría funcionar durante la noche para su caso (Disculpe en ese caso).

myIntent.setFlags (Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_CLEAR_TASK); myIntent.setFlags (Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);

colóquelos antes de llamar a su actividad.