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?

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:

  1. Utilice su propio BufferedInputStream con un buffer más pequeño
  2. Use AssetManager.AssetInputStream como devuelto por AssetManager.open(...) (ver mi respuesta aquí sobre cómo usarlo). Su markSupported() devuelve true .

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.

  • ¿Por qué NO obtengo una excepción de memoria perdida?
  • ¿Cómo puedo convertir el mapa de bits de Android a formato de color NV12?
  • Comparación de imágenes de mapa de bits en Android
  • Dibujar círculo en mapa de bits
  • Android - Lienzo negro cuando se utiliza Flood-Fill
  • Repita la imagen con ImageView en RelativeLayout
  • ¿Qué hace llamar a bitmap.recycle () en API 11+?
  • Azulejo de mapa de bits de Android sólo en X
  • Cómo centrar el texto en android IconGenerator
  • Android - Definir el fondo de la aplicación
  • ¿Cómo puedo imprimir una imagen en una impresora Bluetooth en Android?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.