¿Cuándo borrar el directorio de caché en Android?

Tengo una aplicación que muestra imágenes de Internet (escaparate para el trabajo de diseño). Empiezo a almacenar en caché mi contenido en el directorio de caché interno, pero el contenido de la aplicación puede tomar unos 150 MB en tamaño de caché. Y qué documentos de Android dice:

Siempre debe mantener los archivos de caché usted mismo y mantenerse dentro de un límite razonable de espacio consumido, como 1 MB. Cuando el usuario desinstala su aplicación, estos archivos son eliminados.

Así que eché un vistazo a la aplicación Currents (Galaxy Nexus) y el tamaño de caché para la aplicación es de 110 MB. Pero lo extraño es que aplicaciones como Google Currents y Google Maps almacenan en caché el contenido en algo llamado (USB Storage Data):

enter image description here

Entonces, ¿qué es este ‘Datos de almacenamiento USB’ que utiliza la aplicación anterior? Y si implementa el almacenamiento en caché en su aplicación, ¿realiza un bucle en todos los archivos de la aplicación en caché para obtener el tamaño cada vez que necesita insertar algo y luego compararlo y borrarlo? ¿O sigues almacenando en caché el contenido hasta que Android decide que es hora de limpiar el directorio de caché de algunas aplicaciones?

Estoy realmente interesado en saber cuál es el flujo de administración de caché en Android, o al menos lo que hacen otras aplicaciones con gran contenido para almacenar en caché.

Antes de llegar a su pregunta, aquí hay una breve explicación de los dos tipos de almacenamiento:

Cache

Este es un directorio específico de la aplicación en el sistema de archivos. La intención de este directorio es almacenar datos temporales que su aplicación puede necesitar mantener entre sesiones, pero puede que no sean vitales para mantenerlos para siempre. Normalmente accede a este directorio con Context.getCacheDir() . Esto se mostrará como “Caché” en la configuración de tu aplicación.

Archivos

Al igual que el directorio de caché, su aplicación también tiene un directorio específico de la aplicación para almacenar archivos. Los archivos en este directorio existirán hasta que la aplicación los elimine explícitamente o la aplicación se desinstale. Normalmente accede a este directorio con Context.getFilesDir() . Esto puede aparecer como varias cosas en la pantalla de información de la aplicación, pero en la captura de pantalla esto es “Datos de almacenamiento USB”.

NOTA: Si desea colocar explícitamente en un medio externo (típicamente una tarjeta SD), puede usar Context.getExternalFilesDir(String type) .

La diferencia

Ambos directorios son específicos solo para su aplicación (otras aplicaciones no tienen acceso). Una de las diferencias entre el directorio de caché y de archivos es que si el sistema tiene poco almacenamiento, el primer lugar que va a liberar recursos es desde su directorio de caché. El sistema no eliminará ningún dato del directorio de archivos. Otra diferencia es que el directorio de caché generalmente se puede borrar manualmente desde la pantalla de información de la aplicación. El directorio de archivos también puede funcionar normalmente, pero borrar el directorio de archivos también borrará el directorio de caché.

¿Cuál uso?

Depende de cuán vital es comparar esos datos con la vida útil de su aplicación. Si solo necesita datos para una sesión y duda de que alguna vez necesite usar esos datos nuevamente, entonces no los use. Solo guárdalo en la memoria hasta que no lo necesites. Si sospecha que necesitará reutilizar los datos entre varias sesiones, pero no tiene que guardar una copia impresa, utilice el directorio de caché. Si debe tener estos datos sin importar qué, o si se trata de datos bastante grandes que necesitan almacenamiento persistente, use el directorio de archivos. Aquí hay algunos ejemplos en los que puedo pensar:

  • Caché: un correo electrónico abierto recientemente
    • Una vez abierto, guarde en caché los datos para que cuando el usuario quiera volver a leer ese correo, los cargue instantáneamente en lugar de usar la red nuevamente para recuperar los mismos datos. No necesito mantener esto para siempre, porque eventualmente el usuario terminará con el correo electrónico.
  • Archivos: un archivo adjunto descargado de un correo electrónico
    • Esta es una acción del usuario que dice: “Quiero conservar esta información para que pueda volver a subirla cuando la necesite”. Por lo tanto, colóquelo en el directorio de archivos ya que no quiero borrar este archivo hasta que el usuario lo quiera eliminar.

¿Cuándo debería borrar el directorio de caché?

Desde el Context.getCacheDir() javadocs:

Nota: no debe confiar en que el sistema borre estos archivos por usted; siempre debe tener un máximo razonable, como 1 MB, por la cantidad de espacio que consume con los archivos de caché, y podar esos archivos cuando excede ese espacio.

Utiliza el ejemplo de 1 MB, pero puede ser o no razonable para su aplicación. De todos modos, debe establecer un máximo difícil. La razón de esto simplemente se reduce a diseñar una aplicación responsable. Entonces, ¿cuándo deberías verificar? Yo recomendaría revisar cada vez que quiera poner algo en el directorio de caché. Aquí hay un administrador de caché muy simple:

 public class CacheManager { private static final long MAX_SIZE = 5242880L; // 5MB private CacheManager() { } public static void cacheData(Context context, byte[] data, String name) throws IOException { File cacheDir = context.getCacheDir(); long size = getDirSize(cacheDir); long newSize = data.length + size; if (newSize > MAX_SIZE) { cleanDir(cacheDir, newSize - MAX_SIZE); } File file = new File(cacheDir, name); FileOutputStream os = new FileOutputStream(file); try { os.write(data); } finally { os.flush(); os.close(); } } public static byte[] retrieveData(Context context, String name) throws IOException { File cacheDir = context.getCacheDir(); File file = new File(cacheDir, name); if (!file.exists()) { // Data doesn't exist return null; } byte[] data = new byte[(int) file.length()]; FileInputStream is = new FileInputStream(file); try { is.read(data); } finally { is.close(); } return data; } private static void cleanDir(File dir, long bytes) { long bytesDeleted = 0; File[] files = dir.listFiles(); for (File file : files) { bytesDeleted += file.length(); file.delete(); if (bytesDeleted >= bytes) { break; } } } private static long getDirSize(File dir) { long size = 0; File[] files = dir.listFiles(); for (File file : files) { if (file.isFile()) { size += file.length(); } } return size; } } 

Por supuesto, esto podría ser una operación costosa, por lo que debe planificar el almacenamiento en caché de un hilo de fondo.

Además, esto podría ser tan complicado como lo necesites. En mi ejemplo, supongo que todos los archivos en caché se colocan en la raíz del directorio de caché, por lo que no verifico los posibles subdirectorios. La rutina para eliminar archivos también puede volverse más sofisticada, como eliminar archivos según la fecha de acceso más antigua.

Una cosa a tener en cuenta al decidir almacenar los datos en caché es que siempre debe planear para el caso de que sus datos en caché ya no existan. Tenga siempre una rutina en su lugar para recuperar datos por medios externos cuando su caché no la tenga almacenada. Asimismo, siempre verifique su caché antes de recuperar datos externamente. El objective de la memoria caché es reducir la actividad de la red, los procesos largos y proporcionar una interfaz de usuario receptiva en su aplicación. Así que úsalo responsablemente 🙂

Lo mejor es eliminar la memoria caché de la aplicación cuando la actividad finaliza, de modo que cada vez que la memoria caché se borre cuando llame una nueva actividad.

poner este código en Destroy () para borrar el caché de la aplicación

 @Override protected void onDestroy() { super.onDestroy(); try { trimCache(this); // Toast.makeText(this,"onDestroy " ,Toast.LENGTH_LONG).show(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void trimCache(Context context) { try { File dir = context.getCacheDir(); if (dir != null && dir.isDirectory()) { deleteDir(dir); } } catch (Exception e) { // TODO: handle exception } } public static boolean deleteDir(File dir) { if (dir != null && dir.isDirectory()) { String[] children = dir.list(); for (int i = 0; i < children.length; i++) { boolean success = deleteDir(new File(dir, children[i])); if (!success) { return false; } } } // The directory is now empty so delete it return dir.delete(); } 

Creo que la idea detrás de la memoria caché es escribir todo lo que desees y Android gestionará su tamaño si es demasiado alto.

Debe tener en cuenta que puede escribir archivos en el caché, pero siempre verifica si el archivo aún se guarda cuando intenta acceder a él. Y deja que Android administre la memoria caché.

Depende del tipo de aplicación:

  • Algunas aplicaciones solo usan sesiones individuales y no necesitan recordar ningún dato, por lo que puede borrar el caché cuando lo desee (algunas aplicaciones incluso lo hacen automáticamente en su actividad onStop)
  • La mayoría de las aplicaciones conservan sus datos porque recuerdan su configuración, la cuenta que ha utilizado para iniciar sesión, … En este caso, lo mejor es borrar el caché cuando no usa mucho la aplicación.

También:

 So i took a look at Chrome app (Galaxy Nexus) and the cache size for the application is 110 MB. But what wired is that applications like Google current & Google maps cache the content in something called (USB Storage Data) : 

AFAIK, los datos de almacenamiento USB tienen un uso diferente de la caché: el almacenamiento es para almacenar información específica del progtwig (como mapas para una aplicación de GPS), la memoria caché se usa para almacenar información específica del usuario (como inicios de sesión)

En el caso de los mapas de google: supongo que almacenan los datos del mapa en el almacenamiento usb y mantienen su configuración y el historial de búsqueda en el caché ==> los datos del mapa son específicos de la aplicación, la configuración y el historial de búsqueda son específicos del usuario

De acuerdo con la documentación, el sistema borrará la caché cuando el dispositivo tenga poco almacenamiento interno . Desde API8 tienes el método getExternalCacheDir () que considero útil ya que leo que puedes tener alrededor de 150MB de datos, pero el inconveniente de la caché externa es que tendrás que limpiar tu directorio de caché si es demasiado grande.