2012-04-25 15 views
26

En mi aplicación cuando intento iniciarlo, 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.Causado por: java.lang.OutOfMemoryError: el tamaño del mapa de bits excede el presupuesto de la VM

Editado:

Mi aplicación utiliza la base de datos, y en la primera vez que analizar algunos datos XML y se insertan 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 diario:

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 <unknown> 
    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 <unknown> 
    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.<init>(ImageView.java:118) 
    at android.widget.ImageView.<init>(ImageView.java:108) 

Este es mi código XML:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:orientation="vertical"> 

<RelativeLayout 
    android:id="@+id/RL_Title" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:layout_weight="8" 
    android:onClick="onTitleClick" > 

    <ImageView 
     android:id="@+id/Img_Title_bg" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:scaleType="center" 
     android:src="@drawable/title_bg" /> 

    <Button 
     android:id="@+id/Btn_Title" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_centerVertical="true" 
     android:layout_marginRight="5dp" 
     android:background="@drawable/title_al" 
     android:drawableRight="@drawable/pro" 
     android:gravity="center" 
     android:onClick="onTitleClick" /> 
</RelativeLayout> 

<RelativeLayout 
    android:id="@+id/RL_MainMenu" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:layout_weight="1" android:onClick="onDoNothing"> 

    <ImageView 
     android:id="@+id/ImageView01" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:layout_weight="4" 
     android:src="@drawable/main_bg" android:scaleType="centerCrop"/> 

    <ImageView 
     android:id="@+id/Img_logo" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:layout_weight="4" 
     android:scaleType="center" 
     android:src="@drawable/logo_al" /> 

    <LinearLayout 
     android:id="@+id/LI_Menu" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_above="@+id/RL_ExtraOption" 
     android:layout_alignTop="@+id/Img_logo" 
     android:layout_margin="2dp" 
     android:orientation="vertical" > 

     <ImageButton 
      android:id="@+id/Img_Buyer" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:layout_margin="1dp" 
      android:layout_weight="1" 
      android:background="@drawable/bt_blink" 
      android:onClick="Nextclick" 
      android:scaleType="fitCenter" 
      android:soundEffectsEnabled="true" 
      android:src="@drawable/buyer_icon" /> 

     <ImageButton 
      android:id="@+id/Img_Seller" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:layout_margin="1dp" 
      android:layout_weight="1" 
      android:background="@drawable/bt_blink" 
      android:onClick="Nextclick" 
      android:scaleType="fitCenter" 
      android:src="@drawable/seller_icon" /> 

     <ImageButton 
      android:id="@+id/Img_Lender" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:layout_margin="1dp" 
      android:layout_weight="1" 
      android:background="@drawable/bt_blink" 
      android:onClick="Nextclick" 
      android:scaleType="fitCenter" 
      android:src="@drawable/lender_icon" /> 

     <ImageButton 
      android:id="@+id/Img_myTitleRep" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:layout_margin="1dp" 
      android:layout_weight="1" 
      android:background="@drawable/bt_blink" 
      android:onClick="Nextclick" 
      android:scaleType="fitCenter" 
      android:src="@drawable/my_title_rep_icon_al" /> 

     <ImageButton 
      android:id="@+id/Img_Setup" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:layout_margin="1dp" 
      android:layout_weight="1" 
      android:background="@drawable/bt_blink" 
      android:onClick="Nextclick" 
      android:scaleType="fitCenter" 
      android:src="@drawable/setup_icon" /> 
    </LinearLayout> 

    <RelativeLayout 
     android:id="@+id/RL_ExtraOption" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_alignParentBottom="true" 
     android:background="@drawable/main_bottom_bg" > 

     <TextView 
      android:id="@+id/txt_RepName" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_centerVertical="true" 
      android:layout_marginLeft="10dp" 
      android:textColor="@color/white" 
      android:textSize="@dimen/font_size" /> 

     <TableRow 
      android:id="@+id/TR_ContactRep" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_alignParentRight="true" 
      android:layout_centerVertical="true" 
      android:gravity="center" > 

      <Button 
       android:id="@+id/Btn_ContactRep" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:layout_marginRight="3dp" 
       android:background="@drawable/contact_rep_blink" 
       android:onClick="ContactRep_Click" /> 

      <Button 
       android:id="@+id/Btn_MoreOption" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:layout_marginRight="5dp" 
       android:background="@drawable/main_more_blink" 
       android:onClick="onMoreClick" /> 
     </TableRow> 
    </RelativeLayout> 

    <LinearLayout 
     android:id="@+id/ln_Mainmore" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:background="@drawable/dialog_bg" android:layout_alignParentBottom="true" android:visibility="gone"> 

     <LinearLayout 
      android:id="@+id/LinearLayout02" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_weight="3" 
      android:orientation="vertical" > 
     </LinearLayout> 

     <TableLayout 
      android:id="@+id/TableLayout01" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_weight="1" 
      android:gravity="center" > 

      <TableRow 
       android:id="@+id/TableRow04" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" 
       android:layout_margin="5dp" 
       android:layout_marginTop="20dp" 
       android:gravity="center" > 

       <Button 
        android:id="@+id/Btn_Rate" 
        android:layout_width="match_parent" 
        android:layout_height="match_parent" 
        android:layout_weight="1" 
        android:background="@drawable/property_blue_blink" 
        android:onClick="onRate" 
        android:singleLine="true" 
        android:text="Rate/Testimonial" 
        android:textColor="@color/white" 
        android:textSize="@dimen/font_size" 
        android:textStyle="bold" /> 
      </TableRow> 

      <TableRow 
       android:id="@+id/TableRow01" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" 
       android:layout_margin="5dp" 
       android:gravity="center" > 

       <Button 
        android:id="@+id/btn_SubFeature" 
        android:layout_width="match_parent" 
        android:layout_height="match_parent" 
        android:layout_weight="1" 
        android:background="@drawable/property_blue_blink" 
        android:onClick="onSubFeature" 
        android:singleLine="true" 
        android:text="Submit A Feature" 
        android:textColor="@color/white" 
        android:textSize="@dimen/font_size" 
        android:textStyle="bold" /> 
      </TableRow> 

      <TableRow 
       android:id="@+id/TableRow03" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" 
       android:layout_margin="5dp" 
       android:gravity="center" > 

       <Button 
        android:id="@+id/Btn_ReferFrnd" 
        android:layout_width="match_parent" 
        android:layout_height="match_parent" 
        android:layout_weight="1" 
        android:background="@drawable/property_blue_blink" 
        android:onClick="onReferAFrnd" 
        android:text="Refer A Friend" 
        android:textColor="@color/white" 
        android:textSize="@dimen/font_size" 
        android:textStyle="bold" /> 
      </TableRow> 

      <TableRow 
       android:id="@+id/TableRow02" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" 
       android:layout_margin="5dp" 
       android:gravity="center" > 

       <Button 
        android:id="@+id/Btn_cancel" 
        android:layout_width="match_parent" 
        android:layout_height="match_parent" 
        android:layout_weight="1" 
        android:background="@drawable/property_cancel_blink" 
        android:onClick="onClose" 
        android:text="Cancel" 
        android:textColor="@color/black" 
        android:textSize="@dimen/font_size" 
        android:textStyle="bold" /> 
      </TableRow> 
     </TableLayout> 

     <LinearLayout 
      android:id="@+id/linearLayout2" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_weight="3" 
      android:orientation="vertical" > 
     </LinearLayout> 
    </LinearLayout> 

</RelativeLayout> 

+1

Supongo que tiene un mapa de bits cargado como fondo o fuente de una vista de imagen. ¿De qué tamaño es el mapa de bits? – Simon

+0

Eche un vistazo a la columna de la derecha aquí, en "Relacionados": hay muchas otras preguntas con el mismo tema o similar. – claesv

+0

Ahora es 15.9 KB solamente. Al principio son casi 240 KB y probé a reducir el tamaño a 15.9 KB, pero el problema existe. – Sniper

Respuesta

60

Supongo que el problema no está en su diseño; el problema está en otro lugar en tu código. Y probablemente esté filtrando contexto en algún lugar.

Otra razón probable es que debe crear objetos voluminosos mientras analiza 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 para anular su instancia de colección o borrar el contenido de sus objetos cuando ya no los necesite.

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

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

2) También puede desvincular el drawables asociado 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 link.

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), pero puede cambiar a hashmapsWeakHashmaps, de modo que su memoria podría ser liberado cuando el sistema se queda sin memoria.

4) Puede escalar/cambiar el tamaño de todos sus mapas de bits. Para escalar los mapas de bits se puede intentar 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; 
} 

Tener un vistazo a este link..

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) Usted puede hacer sus objetos SoftReference o Weakreference, de modo que se liberan en una condición de poca memoria.

Una pérdida de memoria muy común que observé se debe a la implementación de clases internas y la implementación de Handler en Activity. This links talks about the same in more detail.

Espero que esto ayude a eliminar su problema.

+0

¿Cómo se decide REQUIRED_SIZE? – NinjaCoder

+2

bien hecho N-Joy, gracias por la ayuda –

+1

Esto es útil para mí buena solución – Dilip

4

Una gran cantidad de dispositivos tienen la memoria muy limitada y restringida 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 y provoca la emisión del 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á utilizando su programa 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 lee en el mapa de bits 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.

Generalmente, 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.

+0

Traté de reducir el tamaño de la imagen, el problema aún persiste. El registro dice que no puede asignar ni siquiera 103 Kb. 04-30 16: 58: 21.833: ​​E/dalvikvm-heap (3654): asignación externa de 105376 bytes demasiado grande para este proceso. 04-30 16: 58: 21.841: E/(3654): VM no nos permite asignar 105376 bytes – Sniper

+0

me puede enviar las imágenes utilizadas en el diseño y lo intentaré en mi extremo –

+0

Mi aplicación utiliza la base de datos , y en el primer momento analiza algunos datos XML e inserta en la base de datos Sqlite. Mi problema de falta de memoria ocurre solo la primera vez. La segunda vez funciona bien. Intenté System.gc(). ¿Hay algún problema con eso? O puedo liberar memoria de cualquier otra manera. – Sniper

4

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

Memory management for Android Apps

6

Este es un problema típico cuando se usa el 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 según las dimensiones de la imagen, por lo que el tamaño del archivo no influye en esto directamente.

Incluso si omite el atributo src en la definición del 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 usar un inSampleSize en BitmapFactory.decodeStream para realizar una reducción de muestreo directamente durante la decodificación (ver Strange out of memory issue while loading an image to a Bitmap object por ejemplo). Esto mismo plantea la pregunta de cómo determinar este factor de escala.

La mejor solución que encontré al manejar grandes imágenes es la sustitución del ImageView con un WebView y cargar algo de HTML mínimo de esta manera:

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

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

<!DOCTYPE html> 
<html> 
<head> 
    <meta charset="UTF-8"> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> 
    <style type="text/css"> 
     body { 
      margin: 0; 
     } 

     img { 
      width: 100%; 
      height: auto; 
      display: block; 
     } 
    </style> 
</head> 
<body> 
    <img src="file:///android_res/drawable/background.png" /> 
</body> 

El motor WebKit que se utiliza en WebView realiza la carga de la imagen ng de una manera mucho más eficiente, para que esos errores de asignación de memoria se hayan ido.

Incluso puede usar diferentes imágenes para retrato y paisaje poniéndolas en drawable-port y drawable-land. Pero luego debe llamar al 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).

0

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.

+0

No creo que esta sea una respuesta 'legítima' – Gattsu

3

Tuve el mismo problema antes y estaba depurando en S4 Android 4.3. La solución fue: copiar las imágenes de la carpeta a carpeta mdpi IPAP (por lo que ahora están en ambos carpeta)

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

3

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

<application>: 

Put:

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 here.

2

Se costuras como ur imagen es de gran tamaño así que se puede decodificar la imagen y utilizar androide: largeHeap = "true". dentro manifiesto de la etiqueta de aplicación

Cuestiones relacionadas