Cómo implementar una galería de imágenes (imágenes locales)
Actualmente estoy haciendo una aplicación para mostrar imágenes de la tarjeta SD. Básicamente usted hace un álbum y agrega cuadros a él, sea de la cámara del selector de MediaStore.
He intentado implementar 2 métodos:
- Descargando la imagen del almacenamiento de firebase usando picasso: excepción de memoria
- Necesita ayuda para comprender la pérdida de memoria en mi aplicación de Android
- ¿Cómo limpiar un ArrayAdapter?
- Android Drawable vs Asset en rendimiento de carga de imágenes
- Subir archivo grande en Android sin error outofmemory
- La aplicación de galería estándar con un BaseAdapter personalizado para devolver una vista
- Un viewpager con PagerAdapter personalizado
No quiero mostrar una vista de cuadrícula, por lo que debe ir a pantalla completa de inmediato. Después de que quiero deshabilitar deslizar hacia la izquierda y la derecha y sólo escuchar los clics.
Atm ambos métodos funcionan en modo retrato. Cuando cambio al paisaje, algunas imágenes solo se dejan
03-20 12:20:56.515: W/OpenGLRenderer(17398): Bitmap too large to be uploaded into a texture
Seguido de errores de memoria insuficiente. Desbordamiento de pila si está lleno con problemas sobre el OOM y la galería, debe reciclar las vistas para que funcionen porque convertView siempre es nulo en el getView de BaseAdapter.
Así que utilicé un reciclador para las vistas, lo limito a 2 vistas y el modo de retrato trabajado para el método 1 (usando la galería). El paisaje todavía me da el mismo problema.
Para el método 2 (viewflipper) maneja las vistas por
@Override public void destroyItem(ViewGroup container, int position, Object object) {
Lo que nunca se llama btw … Sin embargo, el modo retrato funciona aquí. El paisaje todavía se estrella.
Mi método para obtener el mapa de bits:
public static Bitmap getBitmap(Context ctx, int imageId, ImageView target) { String file = getPath(ctx, imageId); BitmapFactory.Options bmOptions = new BitmapFactory.Options(); bmOptions.inJustDecodeBounds = true; BitmapFactory.decodeFile(file, bmOptions); WindowManager mgr = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE); int scaleFactor = 1; if (mgr != null) { // Get the dimensions of the View int targetW = mgr.getDefaultDisplay().getWidth(); int targetH = mgr.getDefaultDisplay().getHeight(); Log.d(TAG, "Image width + height=" + targetW + "," + targetH); int photoW = bmOptions.outWidth; int photoH = bmOptions.outHeight; // Determine how much to scale down the image scaleFactor = Math.min(photoW / targetW, photoH / targetH); } else { Log.d(TAG, "Target is null"); } // Get the dimensions of the bitmap // Decode the image file into a Bitmap sized to fill the View bmOptions.inJustDecodeBounds = false; bmOptions.inSampleSize = scaleFactor; bmOptions.inPurgeable = true; logHeap(ImageHelper.class); Bitmap bm = BitmapFactory.decodeFile(file, bmOptions); if (target != null) { target.setImageBitmap(bm); } return bm; }
Funciona bien, sé que uso el gestor de ventanas para obtener un screensize, pero eso es porque mi ImageView sigue siendo el tamaño (0,0) cuando lo inflado. Después llamo
imgView.setLayoutParams(new Gallery.LayoutParams( Gallery.LayoutParams.FILL_PARENT, Gallery.LayoutParams.FILL_PARENT)); imgView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
Nada parece funcionar …
Tenga en cuenta que no uso drawables o cualquier otro recurso incluido en el APK. Esta galería debe ser capaz de cargar imágenes de la tarjeta SD o de la cámara en cualquier calidad que fueron tomadas. Obviamente la galería debería ser capaz de manejar tantas imágenes como las que hay en el directorio.
¿Podría alguien por favor ayudarme con las siguientes preguntas?
- ¿Hay alguna manera de hacer que la Galería predeterminada vaya a pantalla completa de inmediato y bloquee la vista de cuadrícula? De esta manera sólo necesito un adaptador para proporcionar imágenes en lugar de hacer mis propias vistas. (Tal vez esto resuelve el OOM se bloquea)
- ¿Es mi función de decodificación Bitmap ok? ¿Necesito construir algunos hacks para capturar los cambios del paisaje?
- ¿Cuál es la mejor manera de hacer el tipo de galería que necesito, usando un viewpager o la galería?
- ¿Alguien tiene algún código de ejemplo de una galería de pantalla completa que no se bloquea?
- Implementación de BackStack para Fragmentos en las pestañas de Android
- Cómo liberar la memoria del mapa de bits utilizando imageloader en android?
- Android: Error de OutOfMemory y el backstack
- Error de OutOfMemory del cargador de imágenes universal
- No se puede ejecutar dex: se superó el límite superior de GC en Eclipse
- OutOfMemoryError: Usando una imagen que es 1080 * 1920 haga la página de bienvenida
- Fuera de memoria con imágenes en Android 5
- Fuera de la cadena de memoria de Android
Este es un problema que me he enfrentado a unas pocas veces en el pasado. Google publicó un artículo sobre esto.
El problema está en inSampleSize que usas para decodificar la imagen. Dado que los diferentes dispositivos tienen diferentes pantallas y tamaños de memoria (VM Heap Tamaños que pueden ir de 12 a 64 o más Mb) no se puede decodificar las imágenes de la misma manera en todas ellas. Por ejemplo, una imagen en un dispositivo 320×240 con una memoria Heap de 12Mb debería ser dada enSampleSize mientras que un dispositivo de memoria Heap de 1280×720 64Mb debería usar otro inSampleSize (uno más grande).
El artículo i attack muestra una forma eficiente de renderizar las imágenes para una determinada altura y ancho. Preste especial atención al último segmento de código, "pre-abra" el archivo y calcule el inSampleSize para una "decodificación completa" más adelante.
También quisiera añadir estas recomendaciones.
-
Utilice la función "getBitmap" de una manera asíncrona, llame a un nuevo subproceso oa un asyncTask (esto se hace porque usar el SD toma tiempo y esto hará que su aplicación se cuelgue, sea lenta y dé una mala impresión en low-mid end Dispositivos.
-
Intente utilizar siempre el mismo objeto Bitmap. Evite crear múltiples "Bitmap bitmap = new Bitmap ()". Tienes que darse cuenta de que los mapas de bits cargados se almacenan en RAM y una vez asignado a una vista de su "más difícil" para que el recolector de basura para obtenerlos.
-
Cuando haya terminado de usar un mapa de bits, haga que sea nulo. Esto de esto, imagina que tienes 12 MB de memoria RAM de montón. Su aplicación está usando 8Mb ahora. El recolector de basura empieza y no puede obtener más RAM sin usar. 10 Bitmaps rápidos nunca los hacen nulos después de asignar los datos al ImageView y de alguna manera conservan su referencia. Tomado que cada mapa de bits tomar 500Kb de Ram su aplicación se bloqueará. Haga siempre Bitmaps nulos después de usar.
-
Por último, utilice el DDMS proporcionado en las herramientas de plataforma de Google (puede acceder a él con el eclipse para depurar y ver el uso de memoria, también puede forzar a Garbage Collection a ver cómo se comporta su aplicación).
- Los sockets "localhost" de Android fallan cuando no hay conexión de datos?
- Facebook-esque Popup ¿Cómo?