Error de Android: java.lang.OutOfMemoryError: tamaño de mapa de bits supera el presupuesto de VM

Me encontré con muchas preguntas en stackoverflow con respecto a este error, pero no de ellos encontraron explicando una solución adecuada para mi escenario.

En mi aplicación Android tengo que permitir al usuario hacer clic en un botón para abrir la Galería y seleccionar una imagen. Y luego necesita cargar esa imagen seleccionada específica a un ImageView en mi diseño (UI).

Hacer esto es bastante bien. El siguiente es el código que estoy usando para lograr esto.

En el botón Subir haga clic en ->

Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(Intent.createChooser(intent,"Select Picture"), REQUEST_UPLOAD_IMG); 

Y luego onActivityResult ->

 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { //super.onActivityResult(requestCode, resultCode, data); if(resultCode == Activity.RESULT_OK) { if(requestCode==REQUEST_UPLOAD_IMG) { Uri selectedImageURI = data.getData(); uploadImgVW.setImageURI(selectedImageURI); } else { Toast.makeText(MainActivity.this, "You can only select an Image.", Toast.LENGTH_LONG).show(); } } } 

Pero si el usuario selecciona una imagen con un tamaño más alto (como 2 MB de tamaño), la aplicación salga con el siguiente Error. Pero está bastante bien con imágenes normales (nivel KB) y me pregunto qué puedo hacer para este problema (para manejar esta situación de error). Gracias…

Error ->

 06-20 16:43:58.445: E/AndroidRuntime(2075): FATAL EXCEPTION: main 06-20 16:43:58.445: E/AndroidRuntime(2075): java.lang.OutOfMemoryError: bitmap size exceeds VM budget 

Hay una serie de artículos que describen cómo administrar los mapas de bits de manera eficiente. Mirando su código, carga la imagen sin saber cuán grande es eso y eventualmente se enfrentará a estos problemas, especialmente si carga y procesa muchas imágenes.

La idea descrita en uno de esos artículos es cargar un mapa de bits ya reducido (primero se comprueba el tamaño de la imagen que se va a cargar, luego se calcula el factor de escala descendente y sólo después se cargará la imagen reducida) . Para eso necesitas conocer las dimensiones de ImageView primero, entonces tendrás que usar BitmapFactory.decode (…) ya que tienes un Uri del archivo de destino que se mostrará. Uri a archivo debe ser trivial.

Además, debe comprobar el consumo de memoria en su aplicación también … puede que tenga otros recursos que están colgando en la memoria y necesita limpiarlos. Estoy usando una herramienta muy útil – MAT . Un muy buen artículo sobre esto se puede encontrar aquí . El autor, Patrick Dubroy, realizó una sesión muy interesante en Google IO 2011 sobre este tema. Compruebe que fuera , para mí fue muy útil …

Redimensionar la imagen y luego

 public static Bitmap decodeUri(Context c, Uri uri, final int requiredSize) throws FileNotFoundException { BitmapFactory.Options o = new BitmapFactory.Options(); o.inJustDecodeBounds = true; BitmapFactory.decodeStream(c.getContentResolver().openInputStream(uri), null, o); int width_tmp = o.outWidth , height_tmp = o.outHeight; int scale = 1; while(true) { if(width_tmp / 2 < requiredSize || height_tmp / 2 < requiredSize) break; width_tmp /= 2; height_tmp /= 2; scale *= 2; } BitmapFactory.Options o2 = new BitmapFactory.Options(); o2.inSampleSize = scale; return BitmapFactory.decodeStream(c.getContentResolver().openInputStream(uri), null, o2); } 

O puedes usarlo así

 if(resultCode == RESULT_OK){ Uri selectedImage = data.getData(); InputStream imageStream = null; try { imageStream = getContentResolver().openInputStream(selectedImage); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } Bitmap yourSelectedImage = BitmapFactory.decodeStream(imageStream); profileImage.setImageBitmap(Bitmap.createScaledBitmap(yourSelectedImage , 120, 120, false)); } 

Puedes probar esto …

 BitmapFactory.Options options = new BitmapFactory.Options(); options.inTempStorage = new byte[16*1024]; Bitmap bitmapImage = BitmapFactory.decodeFile(path, options); 
  • Cómo utilizar Eclipse Memory Analyzer Tool (MAT) para analizar un hashmap
  • ¿Hay consejos de administración de memoria para cuidar al crear aplicaciones de Android?
  • Bitmap reciclado con largeHeap habilitado
  • ¿Cómo gestiona la memoria Android?
  • La aplicación android se bloquea sin ninguna excepción al intentar iniciar sesión con google plus
  • Android.view.InflateException: Línea # 2 del archivo XML binario: Error al inflar la clase <unknown>
  • Adb shell dumpsys meminfo - ¿Cuál es el significado de cada celda de su salida?
  • ¿Por qué hay cientos de mapas de bits en la memoria para una aplicación básica para Android?
  • Error de Eclipse: MAT
  • En Android SQLite, trabajar directamente con Cursor es más eficiente en la memoria que crear objetos de modelo?
  • Unbinding drawables onPause () causando una respuesta de navegación que no responde y saltando este paso causa desbordamiento de memoria
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.