76 votes

Quand à vider le cache de dir en Android?

J'ai une application qui affiche des images de l'internet (vitrine pour le concepteur de travail). Je commence la mise en cache de mon contenu dans le cache interne de répertoire, mais le contenu de l'application peut prendre environ 150 MO en taille de la mémoire cache. Et ce android docs dit :

Vous devez toujours conserver les fichiers de cache et de demeurer à l'intérieur d'un limite raisonnable de l'espace consommé, tels que 1 MO. Lorsque l'utilisateur désinstalle votre application, ces fichiers sont supprimés.

Alors j'ai pris un coup d'oeil à l'Courants application (Galaxy Nexus) et la taille du cache de l'application est de 110 MO. Mais ce qui est bizarre, c'est que les applications comme des Courants de Google Et Google Maps cache le contenu dans quelque chose qui s'appelle USB (Stockage de Données) :

enter image description here

Quel est donc ce 'USB de Stockage de Données" que la précédente application utilise. Et si vous mettez en œuvre la mise en cache dans votre application, Ne vous en boucle sur tous les fichiers de votre application dans le cache pour obtenir la taille à chaque fois que vous devez insérer quelque chose et puis de les comparer et de les effacer? Ou gardez-vous de la mise en cache du contenu jusqu'à ce que Android décide de son temps à nettoyer certains de cache de l'application répertoire ?

Je suis vraiment curieux de savoir quel est le flux de la gestion du cache dans Android, ou du moins de ce que d'autres applications ne avec de grands contenus de cache.

191voto

Jason Robinson Points 10878

Avant d'en arriver à votre question, voici une brève explication de ces deux types de stockage:

Cache

Ceci est une application répertoire spécifique sur le système de fichiers. Le but de ce répertoire est de stocker des données temporaires de votre application peut avoir besoin de garder autour, entre les sessions, mais peut-être pas vital pour garder pour toujours. Vous avez généralement accès à ce répertoire, Context.getCacheDir(). Cela fera apparaître comme "Cache" sur les paramètres de votre app.

Fichiers

Comme le répertoire de cache, votre application dispose également d'une application répertoire spécifique pour la tenue de fichiers. Les fichiers dans ce répertoire doit exister jusqu'à ce que l'application explicitement les supprime ou l'application est désinstallée. Vous avez généralement accès à ce répertoire, Context.getFilesDir(). Ce qui peut apparaître comme des choses différentes sur l'application de l'écran d'info, mais dans votre capture d'écran c'est "USB de Stockage de Données".

REMARQUE: Si vous souhaitez explicitement le placer sur un support externe (généralement une carte SD), vous pouvez utiliser Context.getExternalFilesDir(String type).

La Différence

Ces deux répertoires sont spécifiques à votre application (d'autres applications n'ont pas accès). L'une des différences entre le cache et les fichiers de répertoire, c'est que si le système est faible sur le stockage, en premier lieu, il va libérer des ressources à partir de votre répertoire de cache. Le système ne sera pas effacer les données du répertoire des fichiers. Une autre différence est que le répertoire de cache peuvent généralement être effacé manuellement à partir de l'app de l'écran d'info. Le répertoire des fichiers de règle générale, il peut aussi bien, mais en dégageant les fichiers du répertoire effacer le répertoire de cache.

Lequel dois-je utiliser?

Il dépend de l'importance vitale de données par rapport à la durée de vie de votre application. Si vous avez seulement besoin de données pour une seule session et vous doutez de ce que vous aurez jamais besoin d'utiliser que les données de nouveau, alors n'utilisez pas non plus. Il suffit de garder en mémoire jusqu'à ce que vous n'en avez pas besoin. Si vous pensez que vous aurez besoin de réutiliser les données entre plusieurs sessions, mais vous ne pas avoir à conserver une copie papier, utiliser le répertoire de cache. Si vous devez disposer de ces données n'importe quoi, ou si c'est plutôt de données de grande taille que les besoins de stockage persistant, utiliser le répertoire des fichiers. Voici quelques exemples que je pense:

  • Cache - A récemment ouvert un e-mail
    • Une fois ouvert, mettre en cache les données de sorte que lorsque l'utilisateur veut lire que l'e-mail de nouveau, il se charge instantanément plutôt en utilisant le réseau pour récupérer les mêmes données. Je n'ai pas besoin de garder cela pour toujours, parce que finalement l'utilisateur sera fini avec l'e-mail.
  • Fichiers - Une pièce jointe téléchargée à partir d'un e-mail
    • C'est une action de l'utilisateur qui est en train de dire "je veux garder ces données afin que je puisse le tirer en arrière à chaque fois que j'en ai besoin." Par conséquent, le mettre dans le répertoire des fichiers que je ne suis pas toujours sur de vouloir supprimer ce fichier jusqu'à ce que l'utilisateur veut les supprimer.

Quand dois-je effacer le répertoire de cache?

De la Context.getCacheDir() javadoc:

Remarque: vous ne devez pas compter sur le système de suppression de ces fichiers pour vous; vous devriez toujours avoir un maximum raisonnable, tel que 1 MO, pour le quantité d'espace que vous consommez avec les fichiers de cache, et de couper les fichiers en cas de dépassement de l'espace.

Il utilise l'exemple de 1 MO, mais qui peut ou peut ne pas être raisonnable pour votre application. Peu importe, vous devez définir une dur maximale. La raison de cela revient simplement à la conception d'un responsable d'application. Alors, quand devez-vous vérifier? Je recommande de vérifier chaque fois que vous voulez mettre quelque chose dans le répertoire de cache. Voici un simple gestionnaire de cache:

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;
    }
}

Bien sûr, cela pourrait être une opération coûteuse, de sorte que vous devez planifier sur la mise en cache sur un thread d'arrière-plan.

En outre, cela pourrait être aussi compliqué que vous le souhaitez. Dans mon exemple, je suis en supposant que tous les fichiers mis en cache sont placés à la racine du répertoire de cache, donc je n'ai pas de vérifier la présence éventuelle de sous-répertoires. La routine de suppression de fichiers peuvent également devenir de plus en plus sophistiquées, telles que la suppression des fichiers par la plus ancienne date d'accès.

Une chose à garder à l'esprit lorsque vous décidez de mettre des données en cache, c'est que vous devez toujours planifier pour le cas où vos données mises en cache n'existe plus. Toujours avoir une routine en place pour récupérer des données par des moyens externes, lorsque votre cache de ne pas l'avoir dans le stockage. De même, vérifiez toujours votre cache avant de récupérer les données en externe. Le but du cache est de couper vers le bas sur l'activité du réseau, des processus, et de fournir une réponse de l'INTERFACE utilisateur de votre application. Afin de l'utiliser de façon responsable :)

15voto

crony_cd Points 1655

je pense que la meilleure façon de compensation app cache lors de l'activité de la finition, de sorte que chaque moment de vider le cache lors de la nouvelle activité d'appel.

mettez ce code dans onDestroy() pour effacer app cache

@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();
}

1voto

nininho Points 2751

Je pense que l'idée derrière le cache est d'écrire tout ce que vous voulez sur elle et Android va gérer sa taille si elle devient trop élevée.

Vous devez garder à l'esprit que vous pouvez écrire des fichiers dans le cache, mais vérifie toujours si le fichier est enregistré lorsque vous tentez d'accéder. Et laissez android de gérer th cache.

1voto

Andreas Points 714

Dépend du type d'application:

  • Certaines applications utilisent uniquement une seule fois, et n'ont pas besoin de se rappeler de toutes les données, de sorte que vous pouvez vider le cache lorsque vous voulez (certaines applications même le faire automatiquement dans leur onStop activité)
  • La plupart des applications de garder vos données, car ils se souviennent de vos paramètres, le compte que vous avez utilisé pour se connecter,... Dans ce cas, il est préférable de vider le cache lorsque vous n'utilisez pas l'application.

Aussi:

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) :

Autant que je sache, Usb de stockage de données a une utilisation différente de cache: le stockage est de stocker programme spécifique de l'information (comme des cartes pour une application GPS), le cache est utilisé pour stocker des données propres à l'utilisateur (comme les connexions)

Dans le cas de google maps: je suppose qu'ils stockent des données de la carte dans le port usb de stockage, et de conserver vos paramètres et l'historique de recherche dans le cache ==> la carte de données est spécifique à l'application, les paramètres et l'historique de recherche sont propres à l'utilisateur

0voto

Kowlown Points 155

Selon la documentation du système nettoyer le cache lorsque l'appareil est sur le stockage interne. Depuis API8 vous avez getExternalCacheDir() la méthode que je pense utile depuis que j'ai lu, vous pouvez avoir autour de 150 MO de données, mais l'inconvénient de la mémoire cache externe c'est que vous devrez nettoyer votre répertoire de cache-toi si c'est trop gros.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X