2010-12-28 16 views
18

HI en mi aplicación tengo fotos videos etc., en el caso de la imagen que hice la escala, pero me sale la memoria de excepción en algunas ocasiones, ¿cómo puedo manejar la memoria? excepción eficientementeandroid cómo manejar la excepción de memoria

+0

OutOfMemory 'Error' not' Exception'. Hay una gran diferencia entre 'Error' y' Excpetion' –

Respuesta

28

Compruebe que el tamaño de la imagen sea menor que la memoria disponible antes de intentar cargarlo. Por lo tanto, la forma más eficiente de manejar OutOfMemoryException es la arquitectura de su aplicación de forma que nunca intente cargar muchos datos en la memoria para evitar la excepción.

12

OutOfMemory no puede ser manejado. ¿Qué piensas?

La memoria del dispositivo está llena, tiene la excepción y luego hace algo mágico que elimina la excepción y ahora tiene más montón. Eso es imposible, ¿sabes?

OutOfMemory se debe evitar, no se maneja después de que se produzca.

+20

malditamente esto suena tan intenso –

+4

Probablemente la mayoría de los casos donde se obtiene una OutOfMemory involucran la carga de Bitmap (como en esta pregunta) y simplemente no es cierto que no hay nada que puede hacer. En muchos casos, no puede cargar una imagen de N megabytes, pero aún puede cargar una imagen de N/4 megabytes. Use BitmapFactory.Opciones con inSampleSize> = 1, y do inSampleSize * = 2 antes de cada reintento. –

+19

En realidad, esta publicación es incorrecta. La memoria del dispositivo NO está necesariamente llena. Un OutOfMemory se produce cuando no se puede asignar la cantidad de memoria solicitada. Si hay 40 MB disponibles e intenta asignar 45 MB, obtendrá OutOfMemory, pero todavía tiene 40 MB disponibles. – xtempore

8

Se llama al a method in Activity cuando el dispositivo tiene poca memoria, pero esto solo se puede utilizar para desencadenar la limpieza de los archivos de caché. Esto no significa que su proceso de solicitud está saliendo de la memoria.

También podría agregar un bloque try catch para detectar Error o OutOfMemoryError, pero esto sería demasiado tarde.

Manejar grandes cantidades de mapas de bits o grandes mapas de bits es realmente difícil en las aplicaciones de Android. Encontrará algunos consejos sobre este tema en this article de Romain Guy.

También puede encargarse de cargar mapas de bits directamente a la resolución que necesita especificando un tamaño de muestra en el BitmapFactory.options que proporciona a los métodos BitmapFactory.decode *().

+1

Observe que se llama a onLowMemory solo cuando otra aplicación necesita más memoria. No cuando su aplicación está sin memoria. Entonces onLowMemory no se invocará cuando se lanza OutOfMemoryError. – Robert

2

He comenzado a probar esta rutina que carga un jpeg en un ImageView y comprueba si hay memoria insuficiente y vuelve a escalar hasta que encaje.

static public boolean tryJpegRead(ImageView imageView, File fn){ 
if (!fn.exists()){ 
    Log.d("ANDRO_ASYNC",String.format("missing file %s",fn.getAbsolutePath())); 
    return false; 
} 
BitmapFactory.Options o = new BitmapFactory.Options(); 
    for (int i = 1; i<10; i++){ 
     o.inSampleSize = i; 
     o.inJustDecodeBounds = true; 
     BitmapFactory.decodeFile(fn.getAbsolutePath(), o); 
     int h = o.outHeight; 
     int w = o.outWidth; 
     Log.d("ANDRO_ASYNC",String.format("going in h=%d w=%d resample = %d",h,w,o.inSampleSize)); 
     o.inJustDecodeBounds = false; 
     try{ 
      imageView.setImageBitmap(
       Bitmap.createScaledBitmap(
         BitmapFactory.decodeFile(fn.getAbsolutePath(), o), 
         w, 
         h, 
         true)); 
      return true; // only happens when there is no error 
     }catch(OutOfMemoryError E){ 
      Log.d("ANDRO_ASYNC",String.format("catch Out Of Memory error")); 
    //  E.printStackTrace(); 
      System.gc(); 
     }   
    } 
    return false; 
} 
+0

La idea es agradable. ¿Agrega alguna latencia? – drulabs

2

Cuando se trata de errores relacionados con mapa de bits OutOfMemory manipulación, comprobando el tamaño del mapa de bits decodificado es el mejor y por lo que sé única opción. Código sigue:

public static BitmapFactory.Options getBitmapOptionsWithoutDecoding(String url){ 
    BitmapFactory.Options opts = new BitmapFactory.Options(); 
    opts.inJustDecodeBounds = true; 
    BitmapFactory.decodeFile(url, opts); 
    return opts; 
} 

public static int getBitmapSizeWithoutDecoding(String url){ 
    BitmapFactory.Options opts = getBitmapOptionsWithoutDecoding(url); 
    return opts.outHeight*opts.outWidth*32/(1024*1024*8); 
} 

//ref:http://stackoverflow.com/questions/6073744/android-how-to-check-how-much-memory-is-remaining 
public static double availableMemoryMB(){ 
    double max = Runtime.getRuntime().maxMemory()/1024; 
    Debug.MemoryInfo memoryInfo = new Debug.MemoryInfo(); 
    Debug.getMemoryInfo(memoryInfo); 
    return (max - memoryInfo.getTotalPss())/1024; 
} 

public static final long SAFETY_MEMORY_BUFFER = 10;//MB 

public static boolean canBitmapFitInMemory(String path){ 
    long size = getBitmapSizeWithoutDecoding(path); 
    Log.d(TAG, "image MB:"+size); 
    return size <= availableMemoryMB() - SAFETY_MEMORY_BUFFER; 
} 

ref: http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

2

En caso de tener grandes imágenes como fondos o similares, de una manera fácil de evitar que fuera de la memoria, es para mover imágenes de dibujable-xhdpi a dibujable-nodpi, pero ten cuidado, esto cargará el mapa de bits sin ninguna modificación. La buena manera debe utilizarse BitmapFactory.options para adaptarse a su necesidad

0
try { 
// All methods here.... 
} catch(OutOfMemoryException e){ 
// Show an AlertDialog with "Memory is full" title 
// If press ok then starts the process again.. 
} 
1

uso androide: allowBackup = "true", androide: hardwareAccelerated = "false" y android: largeHeap = "true" para resolver este

<application 
     android:allowBackup="true" 
     android:icon="@mipmap/ic_launcher" 
     android:label="@string/app_name" 
     android:roundIcon="@mipmap/ic_launcher" 
     android:hardwareAccelerated="false" 
     android:largeHeap="true" 
     android:theme="@style/AppTheme"> 
Cuestiones relacionadas