Campo BitmapFactory.Options.inTempStorage
Tengo un mapa sin conexión personalizado implementado dibujando mosaicos de mapa de bits en lienzo. Estoy tratando de eliminar las creaciones de objetos para reducir GC corre y por lo tanto hacer el mapa de desplazamiento más suave. Veo en el rastreador de asignación que BitmapFactory.decodeFile (…) siempre crea el objeto byte [16400]. Pensé que fijar el campo inTempStorage de BitmapFactory.Options cambiaría eso:
byte[] buffer = new byte[16*1024]; // ... BitmapFactory.Options options = new BitmapFactory.Options(); options.inPreferredConfig = Config.RGB_565; options.inTempStorage = buffer; Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath(), options);
Pero incluso con este código todavía veo decodeFile crear la matriz byte []. ¿Entonces, cuál es el problema?
- Obtención de mapa de bits de vector dibujable
- Cambiar el tamaño de un mapa de bits
- Android: hyperlink textview a una ubicación de mapa?
- Cómo manejar Loading Images in Android
- Java.lang.outofmemoryerror android.graphics.BitmapFactory.nativeDecodeAsset (Método nativo)
- Cómo capturar el error 'Bitmap demasiado grande para ser cargado en una textura'
- ¿Debo usar Bitmap o Drawable para almacenar en ImageCache en Android?
- Cómo convertir un LinearLayout en imagen?
- Mostrar imágenes desde la carpeta Desplegable con Universal Image Loader
- Android: El código QR generado que usa Zxing tiene márgenes (no es apropiado para el área)
- Android - Mientras maneja una imagen es mejor almacenarla o usarla en memoria temporal?
- Cómo crear mapa de bits de GlSurfaceView
- Cómo crear borde blanco alrededor de mapa de bits?
En resumen, el problema es que cuando se utiliza BitmapFactory.decodeFile(String, Options)
, Android asignará un 16 kB BufferedInputStream
, independientemente de options.inTempStorage
.
Para ser más elaborado: BitmapFactory.decodeFile(String, Options)
es un contenedor alrededor de BitmapFactory.decodeStream(InputStream, Rect, Options)
que utiliza un FileInputStream
. En la implementación de BitmapFactory.decodeStream(InputStream, Rect, Options)
, hay este código :
public static Bitmap decodeStream(InputStream is, Rect outPadding, Options opts) { // ... // we need mark/reset to work properly if (!is.markSupported()) { is = new BufferedInputStream(is, 16 * 1024); } // ... }
Dado que la FileInputStream
markSupported()
devuelve false
, esto significa que independientemente de options.inTempStorage
, se options.inTempStorage
un BufferedInputStream
con un búfer de 16 kB si utiliza BitmapFactory.decodeFile(String, Options)
.
Para evitar esta asignación de 16 kB, puede intentar utilizar BitmapFactory.decodeStream(InputStream, Rect, Options)
directamente con un InputStream
para el cual markSupported()
devuelve true
.
Puedo pensar en dos alternativas que podrían valer la pena examinar:
- Utilice su propio
BufferedInputStream
con un buffer más pequeño - Use
AssetManager.AssetInputStream
como devuelto porAssetManager.open(...)
(ver mi respuesta aquí sobre cómo usarlo). SumarkSupported()
devuelvetrue
.
La primera alternativa podría no ayudar mucho, todavía tendrás una matriz de bytes [] asignada, pero al menos está bajo tu control. La segunda opción podría resultar ser la más fructífera, si sus circunstancias le permiten usar este enfoque.
- Corregir archivo 3GP después de la transmisión desde Android Media Recorder
- Detectar sacudidas de dispositivo en la dirección izquierda o derecha en android?