什么时候清除 Android 中的缓存目录? [英] When to clear the cache dir in Android?

查看:23
本文介绍了什么时候清除 Android 中的缓存目录?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序可以显示来自互联网的图片(设计师作品的展示).我开始在内部缓存目录中缓存我的内容,但应用程序内容可能需要大约 150 MB 的缓存大小.什么 android 文档说:

I have an application that displays pictures from the internet (showcase for designer work). I start caching my content in the internal cache directory, but the app content could take about 150 MB in cache size. And what android docs says :

您应该始终自己维护缓存文件并保持在消耗空间的合理限制,例如 1MB.当用户卸载您的应用程序,这些文件将被删除.

You should always maintain the cache files yourself and stay within a reasonable limit of space consumed, such as 1MB. When the user uninstalls your application, these files are removed.

所以我查看了 Currents 应用程序(Galaxy Nexus),该应用程序的缓存大小为 110 MB.但奇怪的是,像 Google Currents & 这样的应用程序Google 地图将内容缓存在称为(USB 存储数据)的内容中:

So I took a look at the Currents app (Galaxy Nexus) and the cache size for the application is 110 MB. But what's weird is that applications like Google Currents & Google Maps cache the content in something called (USB Storage Data) :

那么之前的应用程序使用的这个USB 存储数据"是什么?如果你在你的应用程序中实现缓存,你是否循环遍历所有 你的应用程序文件每次需要插入东西时缓存来获取大小,然后比较并清除它?或者你会一直缓存内容,直到 Android 决定它的时间来清理一些应用程序缓存目录?

So what is this 'USB Storage Data' that the previous application uses. And if you implement caching in your application, Do you loop over all your application files in cache to get the size every time you need to insert something and then compare and clear it? Or do you keep caching the content until Android decides its time to clean some application cache directory ?

我真的很想知道在 Android 中管理缓存的流程是什么,或者至少其他应用程序如何处理要缓存的大量内容.

I'm really interested to know what is the flow of managing cache in Android, or at least what other applications do with large content to cache.

推荐答案

在我回答你的问题之前,这里是对两种存储类型的简要说明:

Before I get to your question, here's a brief explanation of the two storage types:

这是文件系统上特定于应用程序的目录.此目录的目的是存储您的应用程序可能需要在会话之间保留的临时数据,但对于永久保留它们可能并不重要.您通常使用 Context.getCacheDir() 访问此目录.这将在您的应用设置中显示为缓存".

This is an app-specific directory on the filesystem. The intent for this directory is store temporary data your application may need to keep around between sessions, but may not be vital to keep them forever. You typically access this directory with Context.getCacheDir(). This will show up as "Cache" on your app settings.

与缓存目录一样,您的应用程序也有一个用于保存文件的特定于应用程序的目录.此目录中的文件将一直存在,直到应用程序明确删除它们或卸载应用程序.您通常使用 Context.getFilesDir() 访问此目录.这可以在应用程序信息屏幕上显示为各种内容,但在您的屏幕截图中,这是USB 存储数据".

Like the cache directory, your app also has an app-specific directory for holding files. Files in this directory will exist until the app explicitly deletes them or the app is uninstalled. You typically access this directory with Context.getFilesDir(). This can show up as various things on the app info screen, but in your screenshot this is "USB Storage Data".

注意:如果您想明确放置在外部媒体(通常是 SD 卡)上,您可以使用 Context.getExternalFilesDir(String type).

NOTE: If you want to explicitly place on external media (typically SD card), you can use Context.getExternalFilesDir(String type).

这两个目录都特定于您的应用程序(其他应用程序无权访问).缓存目录和文件目录之间的一个区别是,如果系统存储空间不足,它首先要从缓存目录中释放资源.系统不会清除文件目录中的任何数据.另一个区别是缓存目录通常可以从应用程序信息屏幕手动清除.文件目录通常也可以,但清除文件目录也会清除缓存目录.

Both directories are specific only to your application (other apps do not have access). One of the differences between the cache and files directory is that if the system gets low on storage, the first place it is going to free resources is from your cache directory. The system will not clear any data from the files directory. Another difference is that the cache directory can typically be cleared manually from the app info screen. The files directory typically can as well, but clearing the files directory will also clear the cache directory.

这取决于数据与应用生命周期相比的重要性.如果您只需要一个会话的数据并且您怀疑是否需要再次使用该数据,那么不要使用任何一个.只需将其保存在内存中,直到您不需要它为止.如果您怀疑需要在多个会话之间重用数据,但又没有保留硬拷贝,请使用缓存目录.如果您无论如何都必须拥有这些数据,或者如果它是需要持久存储的相当大的数据,请使用 files 目录.以下是我能想到的一些示例:

It depends on how vital that data is compared to the lifetime of your app. If you only need data for one session and you doubt you'll ever need to use that data again, then don't use either. Just keep it in memory until you don't need it. If you suspect you'll need to reuse the data between multiple sessions, but you don't have to keep a hard copy, use the cache directory. If you must have this data no matter what, or if it's rather large data that needs persistent storage, use the files directory. Here's some examples I can think of:

  • 缓存 - 最近打开的电子邮件
    • 一旦打开,缓存数据,以便当用户想要再次阅读该电子邮件时,它会立即加载,而不是再次使用网络来检索相同的数据.我不需要永远保留它,因为最终用户将完成电子邮件.
    • 这是用户的一项操作,他说我想保留这些数据,以便我可以在需要时将其拉回".因此,将它放在 files 目录中,因为我不想删除该文件,直到用户希望将其删除.

    来自 Context.getCacheDir() javadocs:

    From the Context.getCacheDir() javadocs:

    注意:您不应依赖系统为您删除这些文件;您应该始终有一个合理的最大值,例如 1 MB,用于您使用缓存文件消耗的空间量,并修剪这些文件超过那个空间时.

    Note: you should not rely on the system deleting these files for you; you should always have a reasonable maximum, such as 1 MB, for the amount of space you consume with cache files, and prune those files when exceeding that space.

    它使用 1 MB 的示例,但这对您的应用可能合理,也可能不合理.无论如何,您需要设置一个硬最大值.这样做的原因归结为设计一个负责任的应用程序.那么什么时候应该检查呢?我建议您每次要在缓存目录中放入内容时进行检查.这是一个非常简单的缓存管理器:

    It uses the example of 1 MB, but that may or may not be reasonable for your app. Regardless, you need to set a hard maximum. The reason for this simply comes down to designing a responsible app. So when should you check? I would recommend checking every time you want to put something in the cache directory. Here's a very simple cache manager:

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

    当然,这可能是一项昂贵的操作,因此您应该计划在后台线程上缓存.

    Of course, this could be an expensive operation, so you should plan on caching on a background thread.

    此外,这可能与您需要的一样复杂.在我的示例中,我假设所有缓存文件都放在缓存目录的根目录下,因此我不检查潜在的子目录.删除文件的例程也可以变得更加复杂,例如按最旧的访问日期删除文件.

    Also, this could be as complicated as you need it to be. In my example, I'm assuming all cached files are placed at the root of the cache directory, so I don't check for potential sub-directories. The routine for deleting files can also become more sophisticated, such as deleting files by oldest access date.

    在决定缓存数据时要记住的一件事是,您需要始终为缓存数据不再存在的情况做好准备.当您的缓存中没有数据时,始终有一个例程可以通过外部方式检索数据.同样,在从外部检索数据之前,请始终检查您的缓存.缓存的目的是减少网络活动、长时间的进程,并在您的应用程序中提供响应式 UI.所以负责任地使用它:)

    One thing to keep in mind when deciding to cache data is that you need to always plan for the case that your cached data no longer exists. Always have a routine in place to retrieve data by external means when your cache doesn't have it in storage. Likewise, always check your cache before retrieve data externally. The purpose of the cache is to cut down on network activity, long processes, and provide a responsive UI in your app. So use it responsibly :)

    这篇关于什么时候清除 Android 中的缓存目录?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆