Mostrando entradas con la etiqueta Android. Mostrar todas las entradas
Mostrando entradas con la etiqueta Android. Mostrar todas las entradas

Google retira 13 apps para Android con malware



Hemos conocido que Google acaba de retirar 13 apps para Android con malware.

Como ya te hemos comentado, el asunto de las aplicaciones en Google Play con malware es algo ya conocido y hace muy pocos días se dio un nuevo caso, concretamente dos aplicaciones fueron denunciadas a Google por estar ser presuntamente sospechosas de realizar actividades en nuestro teléfono perjudiciales.

Lista de aplicaciones afectadas


- Crazy Block.

- Cake Blast.

- Honey Comb.

- Jump Planet.

- Cake Blast.

- Jump Planet.

- Tiny Puzzle.

- Cake Blast.

- Jump Planet.

- Just Fire.

- Honey Comb.

- Cake Tower.

- Ninja Hook.

- Piggy Jump.

- Drag Box.

- Eat Bubble.

- Hit Planet.


Todas las apps nombradas en la lista anterior tienen el mismo o parecido malware que Brain Test, por lo que si la tienes instalada en tu teléfono te recomendamos que la desinstales cuanto antes.

Brain Test era una aplicación que estaba disponible en Google Play y que tenía malware que afectaba a nuestro teléfono de manera que podía acceder a los privilegios root e incluso resistir a eliminaciones y reseteo de fábrica del teléfono.

Aparte se descubrió que esa aplicación también podía copiar archivos de /system de manera que solo podrías librarte de el instalado una nueva ROM en tu teléfono. Las aplicaciones de la lista anterior estaría afectadas por el mismo o similar malware.

A pesar de las continuas medidas para la entrada de nuevas aplicaciones en Google Play lo cierto es que parece que todavía algunas apps infectadas logran poder estar en el catálogo de la tienda y por consiguiente ser expuestas a descargarse.

Fuente

Android: juegos infectados en la tienda de Google Play


Hace poco, en ESET descubrimos un curioso ataque furtivo dirigido a usuarios de Android. Se trata de una aplicación que, a pesar de ser un juego normal, tiene un elemento adicional interesante: estaba empaquetada con otra aplicación llamada systemdata resourcea, lo que sin duda es bastante sospechoso. ¿Por qué un juego normal que se descarga desde la tienda oficial Google Play Store incluye otra aplicación llamada “datos del sistema”? Ciertamente, esta aplicación/juego en particular no es una aplicación del sistema, como su nombre intenta sugerir.
Aunque la aplicación empaquetada se coloca inadvertidamente en el dispositivo, necesita pedirle permiso al usuario para poder instalarse. La aplicación móvil que solicita permiso para la instalación se hace pasar por la aplicación “Manage Settings” (Administrar configuración). Tras su instalación, se ejecuta como un servicio en segundo plano.
ESET detecta los juegos que instalan este troyano como Android/TrojanDropper.Mapin y al troyano en sí como Android/Mapin. Según nuestros datos telemétricos, los usuarios de Android en la India son actualmente los más afectados, con el 73,58% de detecciones observadas.
El troyano backdoor toma el control del dispositivo y lo convierte en parte de una botnet, al mando del atacante. El troyano configura temporizadores que retrasan la ejecución del payload malicioso. De este modo, disimula el hecho de que el juego troyanizado es el responsable de la conducta sospechosa.
En algunas variantes de esta infiltración, por lo menos deben transcurrir tres días para que el malware alcance la funcionalidad completa de un troyano. Probablemente sea este retraso lo que le permitió al TrojanDownloader pasar tanto tiempo sin ser detectado por Bouncer, el sistema de prevención de malware de Google.
A continuación, el troyano pide derechos de administrador de dispositivos y empieza a comunicarse con su servidor de C&C remoto. Android/Mapin contiene múltiples funcionalidades, tales como impulsar diversas notificaciones, descargar, instalar e iniciar aplicaciones, y obtener información confidencial del usuario; sin embargo, su principal objetivo parece ser el de mostrar anuncios de pantalla completa en el dispositivo infectado.

Vectores de distribución: Google Play y compañía

Lo más interesante acerca de este troyano es que estuvo disponible para descargar desde fines de 2013 y durante 2014 simulando ser los siguientes juegos:
  • Hill Climb Racing
  • Plants vs Zombies 2
  • Subway Surfers
  • Traffic Racer
  • Temple Run 2 Zombies
  • Super Hero Adventure
El malware se subió a Google Play entre el 24 y el 30 de noviembre de 2013, y el 22 de noviembre de 2014. Según MIXRANK, Plants vs Zombies 2  se descargó más de 10.000 veces antes de que se eliminara del sitio.
En esas mismas fechas, System OptimizerZombie TsunamiTom Cat TalkSuper Hero AdventureClassic Brick Game y las aplicaciones ya mencionadas de Google Play Store, empaquetadas con el mismo backdoor y provenientes de los mismos desarrolladores, se subieron a varios mercados alternativos de aplicaciones para Android.
También se descubrió que el mismo backdoor se había empaquetado junto con otras aplicaciones subidas por el desarrollador PRStudio (no prStudio) en mercados alternativos para Android, en algunos de los cuales se hacía referencia a la tienda oficial Google Play Store. Este desarrollador subió al menos otras cinco aplicaciones con el troyano: Candy crush o Jewel crushRacing rivals,Super maria journeyZombie highway killer y Plants vs Zombies a diversos mercados para Android de terceros.
Todos estos juegos infectados aún están disponibles para descargar desde estos mercados. Las aplicaciones infectadas se descargaron miles de veces. A continuación podemos ver los íconos de los falsos juegos:

Aplicaciones infectadas


Infección: las víctimas deben instalar el malware 24 horas después de la ejecución

La forma en que se ejecuta este malware presenta algunas variaciones. En ciertos casos, se coloca el troyano en el dispositivo y, 24 horas después de que se ejecuta por primera vez la aplicación descargada, le pide a la víctima que lo instale. Este método le resulta menos sospechoso al usuarioy le hace creer que la solicitud para instalar la aplicación proviene del sistema operativo.
Otras versiones del troyano no esperan 24 horas, sino que se inician de inmediato. Todas las variantes se activan después de que cambia la conectividad, cuando se registra un nuevo receptorde transmisión en el manifiesto.
cambio de conectividad
Cuando se cambia la conexión, se le solicita al usuario que instale la “aplicación del sistema”. El malware se hace pasar por Google Play Update Manage Settings.

Si el usuario decide cancelar en lugar de instalar, la solicitud de instalación volverá a aparecer cada vez que se cambie la conexión. El usuario promedio se convencerá de que se trata de una actualización importante y es probable que en algún punto instale la aplicación, aunque más no sea para deshacerse de la notificación insistente. A continuación, el troyano inicia un servicio utilizando su propio receptor de transmisión registrado, a la espera de otro cambio en la conexión.
Cuando se establece una conexión, el malware intenta registrarse en los servidores de Google Cloud Messages (GCM) para poder recibir mensajes. Luego de registrarse en GCM, Android/Mapin registra el dispositivo infectado en su propio servidor. Para ello, envía el nombre de usuario, la cuenta de Google, el código IMEI, el ID de registro y su propio nombre.
Registro del dispositivo en el servidor atacante
Para evitar que lo desinstalen, el troyano exige que el usuario active el “administrador de dispositivos”:
Administrador de dispositivos

Luego, le notifica al servidor remoto si logró activar el administrador de dispositivos correctamente. A continuación, aparece una publicidad en una ventana emergente de pantalla completa (intersticial).  La publicidad intersticial se muestra cada vez que cambia la conectividad. Para entregar estas publicidades, usan indebidamente la aplicación legítima SDK AdMob.

Publicidades intersticiales

Comunicación a través de Google Cloud Messaging

El troyano se comunica con el servidor usando Google Cloud Messaging (GCM), ya que de esta forma puede responder a los comandos que recibe del servidor. Hoy en día, estos tipos de comunicaciones se están haciendo cada vez más frecuentes entre el malware.

Comandos


El troyano no implementa todas su funcionalidades en forma completa, y algunas de las implementadas no se utilizan. Existe la posibilidad de que esta amenaza esté todavía en desarrollo y que sus creadores sigan mejorando el troyano en el futuro. Su objetivo principal, controlado desde el servidor remoto, es entregarle anuncios al usuario final en forma agresiva, mientras que finge ser una aplicación del sistema.

También puede entregar otros programas maliciosos en el dispositivo del usuario. Cuenta con la capacidad de activar o desactivar publicidades intersticiales o de banner; cambiar el ID de editor para los anuncios mostrados; elegir si desea o no mostrarle anuncios al usuario; cambiar el tiempo de retardo entre los anuncios que se muestran; instalar, descargar e iniciar aplicaciones; impulsar notificaciones; revocar los derechos de administrador del dispositivo; cambiar el servidor con el que se comunica el malware; y crear accesos directos en la pantalla principal para direcciones URL que instalan las aplicaciones descargadas.
Después de ejecutar cada tarea recibida mediante GCM, el dispositivo cliente le informa al servidor remoto a través de HTTPS que la tarea se completó con éxito.

Conclusión

El troyano se logró subir sin problemas a la tienda Google Play Store, probablemente debido a que Bouncer no había implementado todas las técnicas de detección de malware pertinentes: en este caso, la emulación de un cambio en la conectividad de red.
Otra pregunta interesante es por qué Bouncer no analizó en forma estática el archivo ejecutable que se entregaba junto con los demás elementos del juego subido. Por este motivo, el troyano permaneció sin ser detectado y se distribuyó abiertamente a los usuarios. El desarrollador “SHSH” subió a la Play Store el juego infectado “Super Hero adventure”, y es posible que existan más aplicaciones suyas en la tienda oficial de Google.
Eventualmente, se eliminaron los troyanos de la tienda de Google Play, pero pasó casi un año y medio sin que fueran detectados. Tal vez debido a este y otros casos similares, Google anunció que, a partir de marzo de 2015, todas las aplicaciones y actualizaciones deben pasar por una revisión humana.
Las mejores prácticas para evitar la descarga de malware desde la tienda oficial de Google consisten en descargar aplicaciones provenientes de desarrolladores de confianza y leer los comentarios de personas que ya las estén usando. También hay que considerar si los permisos que solicita una aplicación para su instalación están justificados.
Fuente: welivesecurity.com

QARK: herramienta para detectar vulnerabilidades

Desde su presentación oficial, algunos aficionados al mundo de la seguridad móvil hemos esperado pacientemente que esta herramienta fuese compartida para poner a prueba sus prometidas bondades. Estoy hablando de QARK, una utilidad para la identificación de vulnerabilidades en aplicaciones para Android que puede ser descargada gratuitamente desde el sitio de la aplicación en Github.

Sobre la herramienta…

La aplicación, cuyo nombre deriva de «Quick Android Review Kit», funciona escaneando de manera estática el código de aplicaciones basadas en Java para identificar fallas que puedan dar pie a una explotación futura o a la fuga de información, intentando fusionar comportamientos de Drozer y Metasploit. Por desgracia, solo se asegura su funcionamiento para plataformas Linux y Mac OS.
Entre sus virtudes –explican sus creadores– se encuentran la creación de reportes con los defectos encontrados detallando la severidad de la falla, su explicación y formas de explotación, y la generación automática de POC.
A través de este entorno de trabajo, un tester, auditor, investigador o programador podrá advertir vulnerabilidades en sus aplicaciones, como ser contenido inseguro dentro de componentes del tipo WebView, incorrecta validación de certificados, susceptibilidad al tapjacking, manejo inseguro de URL, mala gestión de intentos, de claves criptográficas o del almacenamiento en bases de datos que posibilite inyecciones SQL.
No obstante, los desarrolladores de QARK desaconsejan la no realización de auditorías manuales sobre el código de la aplicación. Mientras diversifiquemos la naturaleza de las herramientas y procesos que hacen a la evaluación del aplicativo, mayor será la probabilidad de identificar aquellas fallas que permanecen pasivamente en nuestros sistemas.

¡Manos a la obra!

La herramienta es muy fácil de utilizar. A través del parámetro -s (–source), el usuario puede determinar si el escaneo de vulnerabilidades se dará sobre un APK (asignando el valor 1) o una carpeta de código fuente (con el valor 2).
En el primer caso, será necesario además declarar la ruta al APK en concreto con el parámetro -p. En el segundo, se deberá indicar la ruta al archivo manifiesto (-m) y a la carpeta raíz del código (-c).
Otros parámetros opcionales son -e para la generación de un APK exploit-i para instalar el exploitantes producido en un dispositivo a través de ABD, -d para especificar los mensajes de depuración que se pretende recibir (10=Debug, 20=INFO, 30=Warning, 40=Error) y -r para indicar la ruta donde se espera que se almacenen los reportes generados.
Conocer estos parámetros es criterio suficiente para la correcta utilización de la aplicación; parte del resultado del análisis tras la ejecución de la herramienta se ilustra en la siguiente figura, donde vemos que se brinda además una breve explicación de cada potencial debilidad, característica que la vuelve sumamente útil para ser utilizada por desarrolladores que se inician en la seguridad.

Por su parte, el reporte se genera en formato HTML, permitiendo la exploración rápida de los resultados arrojados según la categoría de análisis a la que pertenece.


En resumen…

QARK permite el análisis rápido de vulnerabilidades, permitiendo identificar brechas comunes en las aplicaciones desde una perspectiva de auditoría de seguridad. Claro que no deja de invalidar la necesidad de un análisis manual del código que pueda revelar fallas más específicas.
Se trata de una herramienta extremadamente sencilla de utilizar, lo que la vuelve especialmente provechosa para desarrolladores de aplicaciones móviles que deseen entender cuáles son los puntos débiles existentes en sus creaciones con el objetivo de producir sistemas más robustos.
Sabemos que esta utilidad evolucionará en un futuro para adquirir nuevas funcionalidades. Solo resta esperar que nuevas versiones sean liberadas. En tanto, para saber más sobre esta aplicación puedes dirigirte a la presentación que la acompaña.
Fuente:welivesecurity.com

Vulnerabilidad en Android permite hackearlo con un MMS


Durante las últimas horas no han cesado de aparecer noticias hablando de la investigación de Joshua Drake, de la empresa Zimperium Mobile Security, quepodría suponer un grave riesgo de seguridad para la mayoría de smartphones con Android.

Este investigador ha descubierto varias vulnerabilidades en el reproductor de medios nativo de Android (Stagefright) que podrían provocar que un atacante escribiese código en el sistema o robase información del dispositivo.

Funcionamiento del ataque

El origen de este agujero de seguridad se oculta entre las miles de líneas de código que componen Android. Stagefright es una librería de medios que se encarga de gestionar varios formatos para que el usuario pueda ver vídeos o escuchar música en su smartphone.

Debido a que la gestión de estos medios tiene que ser rápida y consumir el mínimo de recursos posible, esta librería está desarrollada en el lenguaje C++, más propenso a las corrupciones de memorias que otros lenguajes más modernos como Java.

Para realizar este ataque, el investigador asegura que tan solo se necesita el número de teléfono de la víctima. Con este dato se puede enviar un mensaje MMS (con contenido multimedia) especialmente modificado e incluso, en algunos casos, se podría eliminar el mensaje antes de que el usuario lo viera, quedando solo la notificación de que ha sido recibido.

Si este ataque funciona tal y como lo ha descrito el investigador, estaríamos ante uno de los más peligrosos a los que se han enfrentado los usuarios de Android, puesto que no se requiere que la víctima haga nada como por ejemplo abrir un archivo adjunto a un mensaje, instalar una aplicación o pulsar sobre un enlace. Todo esto se realizaría de forma transparente para el usuario siempre que el teléfono tuviese cobertura.

El hecho de que la víctima no se dé cuenta de que está siendo el objetivo de un ataque supone que muchos podrían tener su smartphone comprometido y no darse cuenta de ello, algo que le permitiría al atacante obtener información muy importante del usuario objetivo.

En las siguientes capturas de pantalla vemos cómo funcionaría supuestamente este ataque en un Nexus 5 con Android Lollipop 5.1.1 instalado:



Versiones de Android afectadas

Según esta investigación, todas las versiones de Android a partir de Froyo (2.2) inclusive serían vulnerables, algo que supone, según algunos estudios, el 95 % de dispositivos o alrededor de 950 millones de usuarios en todo el mundo. Además, las versiones anteriores a Jelly Bean son las que tienen un riesgo mayor, puesto que no incorporan mitigaciones de exploits adecuadas.


Hay que tener en cuenta que Stagefright se compone en realidad de siete vulnerabilidades diferentes, que ya han sido reportadas y se les ha asignado su correspondiente CVE. Además, la empresa que ha publicado esta investigación avisó de la seriedad del problema a Google, lo que hizo que se prepararan y aplicaran parches en el código vulnerable en poco tiempo.

El problema reside en quién va a recibir estos parches. Los usuarios de dispositivos de Google como el smartphone Nexus 6, pueden estar seguros de que verán publicada esta actualización. Otros fabricantes puede que la lancen a sus dispositivos estrella más actuales, pero seguirá quedando una gran mayoría de usuarios sin actualizar debido a que ni los fabricantes ni las operadoras se van a molestar en lanzar esta actualización para aquellos dispositivos considerados obsoletos.

Mitigación del ataque

Parece ser que tan solo una actualización por parte del fabricante podría solucionar este grave problema, algo que ya hemos dicho es bastante improbable que se produzca para cientos de millones de usuarios de Android en sus smartphones.

Así pues, ¿qué solución nos queda? De momento, esperar. No olvidemos que este anuncio se ha producido la semana antes de que empiecen las conferencias de seguridad BlackHat y Defcon en Las Vegas, por lo que es lógico que se trate de ganar notoriedad para que asista el mayor número posible de gente a las charlas que el investigador dará en esa conferencia.

No obstante y de momento, la única información de la que disponemos es la proporcionada por la empresa en la que trabaja este investigador, por lo que deberíamos esperar a ver esta presentación antes de sacar nuestras propias conclusiones. No sería la primera vez que se presentase una vulnerabilidad como extremadamente crítica y luego se viese cómo su alcance se ve limitado a unos escenarios muy concretos.

Por eso recomendamos a los usuarios de Android que no se deshagan todavía de sus dispositivos y esperen a ver en qué consiste realmente este fallo de seguridad y cuáles son las posibilidades reales de sufrir un ataque de estas características.

Fuente: welivesecurity.com

Herramienta de conversión de múltiples tipos de valores



Características:

· Es gratis y no tiene publicidad!, ya no debes preocuparte por un funcionamiento no deseado a cambio de una aplicación de excelencia.
· Envía tus resultados a través del botón "Compartir".
· Opción de autorecortar tus textos (ya no necesitas editarlos antes de procesarlos).
· Múltiples formatos de salida (prefijos, sufijos, entre otros).

Transformaciones soportadas:

· MD5 checksum of files
· SHA1 checksum of files
· Ascii a MD5
· Ascii a RC4
· Ascii a SHA
· Ascii a SHA256
· Ascii a SHA512
· Ascii a Decimal
· Decimal a Ascii
· Ascii a Octal
· Octal a Ascii
· Ascii a Hexadecimal
· Hexadecimal a Ascii
· Ascii a Binario
· Binario a Ascii
· Ascii a Base64
· Base64 a Ascii
· Ascii a Htmlentities
· Ascii a Urlencode
· Ascii a Inyección SQL en Dword
· Y mucho más!

Aun se esperan muchas mejoras adicionales como la opción de cifrar y descifrar mensajes sms, correos, mensajes de watsapp, más algoritmos, traducciones en mas idiomas y mucho más.

Algunas capturas de pantalla de la nueva versión:

 



Buenas practicas con Bitmap


Cargando grandes mapas de bits de manera eficiente

Muchas veces tratamos de cargar una imagen de tamaño muy grande en un espacio muy pequeño, y esto funciona, pero no de la manera que esperamos. Al crear un listView con una colección de Bitmap mal implementado, nos daremos cuenta que al deslizar nuestra lista, esta se torna pesada y torpe. Esto es por el tamaño de las imágenes que hemos cargado en cada Bitmap.

Por ejemplo, no vale la pena cargar una imagen de 1024x768 píxeles en la memoria si se mostrará en una miniatura de 128x96 píxeles en un imageView. La mejor practica para evitar esto es reducir el tamaño de imagen que se va a crear en el Bitmap al que se calcula que uno va a usar. Para esto utilizamos la opción inSampleSize, esta opción lo que hace es indica la escala que se utilizara para reducir dicha imagen. Por ejemplo, una imagen con resolución 2048x1536 que se cargara con un inSampleSize de 4 produce un mapa de bits de aproximadamente 512x384, cargando esto en memoria utiliza 0.75MB en lugar de 12 MB para la imagen completa.

Una pregunta común es, como saber que valor al inSampleSize debo colocar? Pues hay un método para calcular dicho tamaño de manera automática, que es el siguiente.

Código: Text
  1. public static int calculateInSampleSize(
  2.             BitmapFactory.Options options, int reqWidth, int reqHeight) {
  3.     final int height = options.outHeight;
  4.     final int width = options.outWidth;
  5.     int inSampleSize = 1;
  6.     if (height > reqHeight || width > reqWidth) {
  7.         final int halfHeight = height / 2;
  8.         final int halfWidth = width / 2;
  9.         while ((halfHeight / inSampleSize) > reqHeight
  10.                 && (halfWidth / inSampleSize) > reqWidth) {
  11.             inSampleSize *= 2;
  12.         }
  13.     }
  14.     return inSampleSize;
  15. }
  16.  

Este método recibe como parámetros el elemento options que utilizaremos para crear nuestro Bitmap, el Width y Height que deseamos que tenga nuestro Bitmap y devuelve un valor de tipo int el cual sera nuestro valor a colocar en inSampleSize para obtener este tamaño deseado.

Para utilizar este método, primero debemos decodificar con la opción inJustDecodeBounds establecida en true, se pasan el options y luego decodificar de nuevo usando el nuevo valor de  inSampleSize y inJustDecodeBounds establecido esta ves en false.

Código: Text
  1. public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
  2.         int reqWidth, int reqHeight) {
  3.     // First decode with inJustDecodeBounds=true to check dimensions
  4.     final BitmapFactory.Options options = new BitmapFactory.Options();
  5.     options.inJustDecodeBounds = true;
  6.     BitmapFactory.decodeResource(res, resId, options);
  7.     // Calculate inSampleSize
  8.     options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
  9.     // Decode bitmap with inSampleSize set
  10.     options.inJustDecodeBounds = false;
  11.     return BitmapFactory.decodeResource(res, resId, options);
  12. }
  13.  

Este método hace que sea fácil de cargar un mapa de bits de tamaño arbitrariamente grande en un ImageView que muestra una miniatura de 100x100 píxeles, como se muestra en el siguiente código de ejemplo:

Código: Text
  1. mImageView.setImageBitmap(
  2.     decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));
  3.  

Ahora bien una ves implementado esto en el caso que dijimos anteriormente se puede notar una gran diferente la fluidez al desplazar nuestra lista, pero esto no queda acá. Las personas que no nos conformamos con poco notaremos que aun la lista de desplaza con cierto retraso que no es nada agradable a la vista. Esto sucede porque cada ves que deslizamos y mostramos los items ocultos en la lista se vuelve a calcular y a cargar la imagen en los Bitmap y todo este proceso se produce en el hilo principal, lo cual tenemos que evitar, entonces el siguiente paso es hacer este proceso de cargado en un hilo secundario, para ello utilizaremos AsyncTask.

Procesando Bitmap en un hilo secundario

La clase AsyncTask proporciona una manera fácil de ejecutar algún trabajo en un subproceso de fondo y publicar los resultados de vuelta en el subproceso de interfaz de usuario. Para usarlo, se crea una subclase y se sobrescriben los métodos proporcionados. Un ejemplo de la carga de una imagen de gran tamaño en un imageView usando AsyncTask y el método creado anteriormente  decodeSampledBitmapFromResource ():

Código: Text
  1. class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
  2.     private final WeakReference<ImageView> imageViewReference;
  3.     private int data = 0;
  4.     public BitmapWorkerTask(ImageView imageView) {
  5.         // Use a WeakReference to ensure the ImageView can be garbage collected
  6.         imageViewReference = new WeakReference<ImageView>(imageView);
  7.     }
  8.     // Decode image in background.
  9.     @Override
  10.     protected Bitmap doInBackground(Integer... params) {
  11.         data = params[0];
  12.         return decodeSampledBitmapFromResource(getResources(), data, 100, 100));
  13.     }
  14.     // Once complete, see if ImageView is still around and set bitmap.
  15.     @Override
  16.     protected void onPostExecute(Bitmap bitmap) {
  17.         if (imageViewReference != null && bitmap != null) {
  18.             final ImageView imageView = imageViewReference.get();
  19.             if (imageView != null) {
  20.                 imageView.setImageBitmap(bitmap);
  21.             }
  22.         }
  23.     }
  24. }
  25.  

Podemos observar que el constructor recibe un imageView el cual sera el que utilizaremos para cargar el Bitmap, el método doInBackground() ejecuta el método decodeSampledBitmapFromResource() en segundo plano y retorna un Bitmap el cual lo va a recibir el método onPostExecute() el cual se encargar de plasmar los resultados en la interfaz principal.

Para comenzar a cargar el mapa de bits de forma asíncrona, basta con crear una nueva tarea y ejecutarlo:

Código: Text
  1. public void loadBitmap(int resId, ImageView imageView) {
  2.     BitmapWorkerTask task = new BitmapWorkerTask(imageView);
  3.     task.execute(resId);
  4. }
  5.  

Observamos que la ejecutar la tarea en segundo plano se le pasa una variable resId, el cual es el id con la ruta de la imagen a cagar.

Almacenando un Bitmap en cache

Al ver los resultados que nos arroja el paso anterior podemos observar que el deslizamiento de nuestra lista es muy veloz, pero que tiene un pequeño problema. Las imágenes tardan en cargarse, y esto es algo esperado ya que el proceso de cargar los item de la lista en el hilo principal no van a esperar ah que termine el proceso en el hilo secundario, entonces se formara una desincronización a la hora de cargar los datos de cada item, por mas que simplemente sean microsegundos, esto es algo que se nota notablemente en la UI e irritaría mucho al usuario.

Entonces como solucionamos este problema? Cargando cada Bitmap en cache.
Una memoria caché ofrece un acceso rápido a los Bitmap a costa de ocupar memoria valiosa de la aplicación. La clase LruCache esta especialmente adecuado para la tarea de Bitmap en caché.

Con el fin de elegir un tamaño adecuado para el LruCache, un número de factores deben ser tomados en consideración, por ejemplo:

 -  ¿Cuántas imágenes estará en pantalla a la vez? ¿Cuántos tienen que estar disponibles listos para entrar en la pantalla?
 -  ¿Cuál es el tamaño de la pantalla y la densidad del dispositivo? Un dispositivo de alta densidad (xhdpi) como Galaxy Nexus tendrá un caché más grande para mantener el mismo número de imágenes en la memoria en comparación con un dispositivo como Nexus S (IPAP).
 -  ¿Con qué frecuencia se accederá a las imágenes? ¿Algunos acceder con mayor frecuencia que los demás? Si es así, tal vez usted puede querer mantener ciertos artículos siempre en la memoria o incluso tener varios objetos LruCache para diferentes grupos de mapas de bits.
 -  ¿Puede equilibrar la calidad contra cantidad? A veces puede ser más útil para almacenar un mayor número de Bitmap de menor calidad.

No hay un tamaño específico o fórmula que se adapte a todas las aplicaciones, es cuestión de cada uno analizar su consumo y llegar a una solución adecuada. Una caché que es demasiado pequeña causa sobrecarga adicional sin ningún beneficio, una memoria caché que es demasiado grande  puede devolver excepciones java.lang.OutOfMemory y dejar al resto de su aplicación poca memoria para trabajar. Un ejemplo de la creación de un LruCache para Bitmap:

Código: Text
  1. private LruCache<String, Bitmap> mMemoryCache;
  2. @Override
  3. protected void onCreate(Bundle savedInstanceState) {
  4.     ...
  5.     // Get max available VM memory, exceeding this amount will throw an
  6.     // OutOfMemory exception. Stored in kilobytes as LruCache takes an
  7.     // int in its constructor.
  8.     final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
  9.     // Use 1/8th of the available memory for this memory cache.
  10.     final int cacheSize = maxMemory / 8;
  11.     mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
  12.         @Override
  13.         protected int sizeOf(String key, Bitmap bitmap) {
  14.             // The cache size will be measured in kilobytes rather than
  15.             // number of items.
  16.             return bitmap.getByteCount() / 1024;
  17.         }
  18.     };
  19.     ...
  20. }
  21. public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
  22.     if (getBitmapFromMemCache(key) == null) {
  23.         mMemoryCache.put(key, bitmap);
  24.     }
  25. }
  26. public Bitmap getBitmapFromMemCache(String key) {
  27.     return mMemoryCache.get(key);
  28. }
  29.  

Ahora cuando vallamos a cargar un Bitmap en un imageView, primero comprobaremos que este Bitmap no esta ya cargado en cache. En caso de que este en cache, evitaremos todo el proceso de redimensionamiento echo anteriormente y simplemente lo traeremos de la cache, caso contrario haremos los pasos mencionados anteriormente y almacenaremos ese Bitmap en cache si no existe, para que la próxima ves que tengamos que cargarlo, lo traigamos de cache.

Código: Text
  1. public void loadBitmap(int resId, ImageView imageView) {
  2.     final String imageKey = String.valueOf(resId);
  3.     final Bitmap bitmap = getBitmapFromMemCache(imageKey);
  4.     if (bitmap != null) {
  5.         mImageView.setImageBitmap(bitmap);
  6.     } else {
  7.         mImageView.setImageResource(R.drawable.image_placeholder);
  8.         BitmapWorkerTask task = new BitmapWorkerTask(mImageView);
  9.         task.execute(resId);
  10.     }
  11. }
  12.  

En la clase BitmapWorkerTask creada anteriormente solo debemos agregar la linea de código que se encarga de cargar este nuevo Bitmap en cache.

Código: Text
  1. class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
  2.     ...
  3.     // Decode image in background.
  4.     @Override
  5.     protected Bitmap doInBackground(Integer... params) {
  6.         final Bitmap bitmap = decodeSampledBitmapFromResource(
  7.                 getResources(), params[0], 100, 100));
  8.         addBitmapToMemoryCache(String.valueOf(params[0]), bitmap);
  9.         return bitmap;
  10.     }
  11.     ...
  12. }
  13.  

Y eso seria todo. Ya tenemos una lista que carga por única vez los Bitmap y luego hace petición a cache, la eficiencia de esto es muy grande y los resultados son muy notorios.

Para realizar este manual me base en la información oficial de Google la cual colocare a continuación.

Loading Large Bitmaps Efficiently
Processing Bitmaps Off the UI Thread
Caching Bitmaps

Autor: Leandro Vitale