Excepción de memoria, cuando se trata de mapas de bits
Estoy trabajando en una aplicación donde tengo imágenes que se descargan de forma asíncrona para SlideShows. One SlideShow contiene 10 diapositivas, por lo tanto, se descargan 10 imágenes cuando se abre la presentación de diapositivas. Después de que desplácese a través de 10-15 presentaciones de diapositivas aproximadamente comienzo a conseguir la advertencia de la memoria y después de la excepción en la huella y la aplicación se bloquea.
Aquí está el rastro:
- Buscando en el diccionario de Oxford
- Diferencia entre e.getMessage () y e.getLocalizedMessage ()
- Dagger para Android: Inyección de una actividad en el gráfico de objetos después de llamar a setContentView
- Expresión regular de Android para obtener enlaces de la fuente de la página web
- Loopj Android Async Http - onFailure no disparado
12-23 12:23:53.124: ERROR/dalvikvm-heap(3067): 45850-byte external allocation too large for this process. 12-23 12:23:53.134: ERROR/dalvikvm(3067): Out of memory: Heap Size=13127KB, Allocated=11913KB, Bitmap Size=11407KB 12-23 12:23:53.134: ERROR/GraphicsJNI(3067): VM won't let us allocate 45850 bytes 12-23 12:23:53.134: DEBUG/skia(3067): --- decoder->decode returned false 12-23 12:23:53.134: WARN/dalvikvm(3067): threadid=46: thread exiting with uncaught exception (group=0x400259f8) 12-23 12:23:53.134: ERROR/AndroidRuntime(3067): FATAL EXCEPTION: Thread-1016 12-23 12:23:53.134: ERROR/AndroidRuntime(3067): java.lang.OutOfMemoryError: bitmap size exceeds VM budget 12-23 12:23:53.134: ERROR/AndroidRuntime(3067): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method) 12-23 12:23:53.134: ERROR/AndroidRuntime(3067): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:468) 12-23 12:23:53.134: ERROR/AndroidRuntime(3067): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:332) 12-23 12:23:53.134: ERROR/AndroidRuntime(3067): at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697) 12-23 12:23:53.134: ERROR/AndroidRuntime(3067): at android.graphics.drawable.Drawable.createFromStream(Drawable.java:657) 12-23 12:23:53.134: ERROR/AndroidRuntime(3067): at com.nbcu.myApp.appsupport.AsyncImageLoader.loadImageFromUrl(AsyncImageLoader.java:98) 12-23 12:23:53.134: ERROR/AndroidRuntime(3067): at com.nbcu.myApp.appsupport.AsyncImageLoader$2.run(AsyncImageLoader.java:70) 12-23 12:23:53.154: WARN/ActivityManager(96): Force finishing activity com.nbcu.myApp.activities/com.nbcu.myApp.controllers.StoriesListController 12-23 12:23:53.224: ERROR/dalvikvm-heap(3067): 45850-byte external allocation too large for this process. 12-23 12:23:53.234: DEBUG/SurfaceFlinger(96): Layer::setBuffers(this=0x2fabc0), pid=96, w=1, h=1 12-23 12:23:53.234: ERROR/dalvikvm(3067): Out of memory: Heap Size=13127KB, Allocated=11948KB, Bitmap Size=11407KB 12-23 12:23:53.234: ERROR/GraphicsJNI(3067): VM won't let us allocate 45850 bytes 12-23 12:23:53.234: ERROR/Error(3067): Message = java.lang.OutOfMemoryError: bitmap size exceeds VM budget
El código en el que se descargan las imágenes es:
public void run() { Looper.prepare(); for (int i = 0; i < slides.size(); i++) { try { final SlideShowItem story = slides.get(i); if (story.getImage() == null) { Drawable cachedImage = Utils.database.getRSSImage(Constants.StoriesTable, story.getItemId()); if (cachedImage != null) { story.setImage(cachedImage); } else { cachedImage = asyncImageLoader.loadDrawable(story.getImagePath(), new ImageCallback() { public void imageLoaded(Drawable imageDrawable, String imageUrl) { story.setImage(imageDrawable); Utils.database.storeRSSItemImage(Constants.StoriesTable, imageDrawable, story.getItemId()); } }); } } Thread.sleep(500); } catch (Exception e) { e.printStackTrace(); } } Looper.loop(); }
El código para loadDrawable () es:
public Drawable loadDrawable(final String imageUrl, final ImageCallback imageCallback) { final Handler handler = new Handler() { public void handleMessage(Message message) { imageCallback.imageLoaded((Drawable) message.obj, imageUrl); } }; new Thread() { public void run() { Drawable drawable = loadImageFromUrl(imageUrl); // System.out.println("image url: " + imageUrl); if (drawable != null) { Message message = handler.obtainMessage(0, drawable); handler.sendMessage(message); } } }.start(); return null; }
Y el código para loadImageFromURL () es:
public static Drawable loadImageFromUrl(String url) { Drawable image = null; try { InputStream in = (java.io.InputStream) new java.net.URL(url).getContent(); if (in != null) { image = Drawable.createFromStream(in, "image"); } in.close(); } catch (Exception ex) { // ex.printStackTrace(); Log.v("Exception ", "Asyn Image.In LoadImageFromURL Message: " + ex.toString()); } return image; }
Una vez descargadas las imágenes, se almacenan en caché. No puedo encontrar una solución para evitar esta excepción. ¿Cuál podría ser la razón? También he intentado establecer vistas de imagen nula cuando la actividad se destruye, pero no ha hecho nada para mí? Cualquier ayuda es apreciada. Gracias por adelantado.
- plataforma cordova añadir android obtener un error en JAVA_HOME
- Obtener el número de teléfono en formato XXX-XXX-XXXX desde el cuadro edittext en android
- ¿Cómo puedo convertir datos JSON presentes en una URL en una cadena JSON en java o android?
- ¿Existe alguna razón para usar el patrón de observador en un receptor de difusión?
- Firmado APK tiene diferentes Key-Hash para Facebook
- No se puede realizar esta acción después de onSaveInstanceState (onClick preference)
- Cómo obtener el objeto Mat desde el byte en openCV android?
- 'Private static final' miembro de la clase de prueba de unidad de Android cambia el valor a null
Android es un sistema operativo móvil. Tiene una memoria limitada, por lo que no se puede almacenar en caché todos los slides.size (). Supongo que el tamaño> 15. Por ejemplo, estoy corriendo un algoritmo FastCV con una imagen HD como marcadores, 250000 x 180000 píxeles y si ejecuto el programa en la PC, funciona bien, si lo hago en el teléfono móvil no, porque el Memoria no es suficiente.
Creo que se puede resolver el problema, si sólo caché 10 – 15 imágenes, depende del tamaño de las mismas. Si se desplaza, entonces el caché nuevo en la memoria ya utilizada.
Considere la posibilidad de reducir la escala de las imágenes almacenadas en caché al tamaño de las vistas con las que se utilizan. Por ejemplo, puede utilizar el método siguiente en su loadImageFromUrl(String url)
:
// Determining the original size of the image: BitmapFactory.Options optnsSizeOnly = new BitmapFactory.Options(); optnsSizeOnly.inJustDecodeBounds = true; InputStream inputStreamSizeOnly = (java.io.InputStream) new java.net.URL(url).getContent(); BitmapFactory.decodeStream(inputStreamSizeOnly, null, optnsSizeOnly); int widthOriginal = optnsSizeOnly.outWidth; // Determining the scale ratio. // Note, it's just an example, you should use more sophisticated algorithm: int ratio = widhtOriginal / widthView; // widthView is supposed to be known // Now loading the scaled image: BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = ratio; InputStream inputStream = (java.io.InputStream) new java.net.URL(url).getContent(); Bitmap bitmap = BitmapFactory.decodeStream(inputStream, null, options);
Debe utilizar una clase de inicialización perezosa perezosa . Me gustaría ir para el uso de 3 imágenes a la vez, la imagen que se muestra actualmente y los próximos dos. De esta manera, cuando el usuario está viendo image1, image2 e image3 ya están en la memoria. Cuando el usuario se desliza a image2, image4 debe ser cargado en la imagen anterior buffer1 (image3 todavía está en la memoria) Espero que esto ayude
- Android / Eclipse: ¿dónde escribir líneas de comandos como "emulator -wipe-data"?
- Android determinar si contexto de actividad o contexto de aplicación