在Android应用程序中以编程方式清除缓存

100

如何以程序方式清除 Android 应用程序中的缓存?我已经使用以下代码,但它好像对我没有作用。

@Override
protected void onDestroy() {
    // TODO Auto-generated method stub
    super.onDestroy();
    clearApplicationData();
}

public void clearApplicationData() {
    File cache = getCacheDir();
    File appDir = new File(cache.getParent());
    if (appDir.exists()) {
        String[] children = appDir.list();
        for (String s : children) {
            if (!s.equals("lib")) {
                deleteDir(new File(appDir, s));
                Log.i("EEEEEERRRRRRROOOOOOORRRR", "**************** File /data/data/APP_PACKAGE/" + s + " DELETED *******************");
            }
        }
    }
}

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

    return dir.delete();
}

来自我的安卓手机的图片


2
请检查 getExternalCacheDir()。 - Patrick
@for3st 我们能否仅为webview清除缓存? - Rizwan Ahmed
2
WebView.clearCache(boolean includeDiskFiles) 将清除应用程序中所有 WebView 的缓存。 - Patrick
可能是如何清除Android缓存的重复问题。 - Yksh
@RizwanAhmed,你找到上述问题的解决方案了吗? - Vishwa Pratap
@VishwaPratap,下面被接受的答案是解决方案。 - Rizwan Ahmed
12个回答

171
如果您想删除自己应用的缓存,那么只需删除缓存目录即可完成所有操作!
public static void deleteCache(Context context) {
    try {
        File dir = context.getCacheDir();
        deleteDir(dir);
    } catch (Exception e) { e.printStackTrace();}
}

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;
            }
        }
        return dir.delete();
    } else if(dir!= null && dir.isFile()) {
        return dir.delete();
    } else {
        return false;
    }
}

2
这段代码永远不会删除文件。当dir.isDirectory() == false时,它只会返回false。由于无法删除非空目录,因此这种方法行不通。你应该添加一个else:if (dir != null && dir.isDirectory()) { ... } else if(dir.isFile()) { return dir.delete(); } - Pierfrancesco Soffritti
@dhams 这个方法是否也清除我的共享首选项数据?因为我想保留它,只清除缓存中的图像!!! - Saty
3
@Saty:不,这并没有清除共享首选项。 - Taifun
1
他们在文档中写道,我们不需要额外的权限来执行此操作。 “应用程序无需额外的权限即可读取或写入返回路径,因为该路径位于其私有存储中。” https://developer.android.com/reference/android/content/Context.html#getCacheDir() - YTerle
在Android N中,不支持上述代码,会抛出空数组,请更新答案。 - Yogesh Rathi
显示剩余5条评论

110

Kotlin有一个一行代码的解决方案

context.cacheDir.deleteRecursively()

11
完美的答案,这也应该在Java中可用: context.getCacheDir().deleteRecursively() - JJ Du Plessis
你确定这不会以某种方式破坏缓存目录吗?当我运行了这个代码,然后运行 File.createTempFile("download", null) 时,我得到了 "java.io.IOException: open failed: ENOENT (No such file or directory)" 的错误提示。 - AndreKR

20

dhams的答案是正确的(虽然经过多次编辑),但正如许多代码的编辑所示,编写正确且健壮的代码来删除目录(包括子目录)是困难的。因此,我强烈建议使用Apache Commons IO或其他可以为您执行此操作的API:

import org.apache.commons.io.FileUtils;

...

// Delete local cache dir (ignoring any errors):
FileUtils.deleteQuietly(context.getCacheDir());

PS:如果使用context.getExternalCacheDir()返回的目录,也要将其删除。

为了能够使用Apache Commons IO,请在build.gradle文件的dependencies部分中添加以下内容:

compile 'commons-io:commons-io:2.4'

3
现在Gradle文件中的编译行将是implementation 'commons-io:commons-io:2.5'。我先尝试了2.6版本,但是出现了NoSuchMethodException等错误,所以目前请使用2.5版本。最新版本在这里:mvnrepository.com/artifact/commons-io/commons-io - Juan Ignacio Avendaño Huergo

6

如果你在使用Kotlin:

context.cacheDir.deleteRecursively()

5

我认为你应该在super.OnDestroy()之前放置clearApplicationData()

当应用程序被关闭时,它无法处理任何方法。


3
我应该从哪里找到这个方法? - Amarjit
1
基本的Android活动生命周期。在继续之前最好先阅读一下。https://developer.android.com/guide/components/activities/activity-lifecycle.html或者你是指clearApplicationData()吗?OP自己写的。 - Dennie

4

试试这个

@Override
protected void onDestroy() {
    // TODO Auto-generated method stub
    super.onDestroy();
    clearApplicationData();
}

public void clearApplicationData() {
    File cache = getCacheDir();
    File appDir = new File(cache.getParent());
    if (appDir.exists()) {
        String[] children = appDir.list();
        for (String s : children) {
            if (!s.equals("lib")) {
                deleteDir(new File(appDir, s));
                Log.i("EEEEEERRRRRROOOOOOORRRR", "**************** File /data/data/APP_PACKAGE/" + s + " DELETED *******************");
            }
        }
    }
}

public static boolean deleteDir(File dir) {
    if (dir != null && dir.isDirectory()) {
        String[] children = dir.list();
        int i = 0;
        while (i < children.length) {
            boolean success = deleteDir(new File(dir, children[i]));
            if (!success) {
                return false;
            }
            i++;
        }
    }

    assert dir != null;
    return dir.delete();
}

我该如何使用您的代码并仅删除 shared_prefs 缓存?你能帮我吗? - Karan Israni
将 if (!s.equals("lib")) 替换为 if (s.equals("shared_prefs"))。 - taxo

2

我不确定,但我也看到了这段代码。 这个代码会更快地工作,而且在我看来也很简单。 只需获取您的应用程序缓存目录并删除目录中的所有文件。

public boolean clearCache() {
    try {

        // create an array object of File type for referencing of cache files   
        File[] files = getBaseContext().getCacheDir().listFiles();

        // use a for etch loop to delete files one by one
        for (File file : files) {

             /* you can use just [ file.delete() ] function of class File
              * or use if for being sure if file deleted
              * here if file dose not delete returns false and condition will
              * will be true and it ends operation of function by return 
              * false then we will find that all files are not delete
              */
             if (!file.delete()) {
                 return false;         // not success
             }
        }

        // if for loop completes and process not ended it returns true   
        return true;      // success of deleting files

    } catch (Exception e) {}

    // try stops deleting cache files
    return false;       // not success 
}

通过getBaseContext().getCacheDir().listFiles()方法获取缓存文件夹中的所有文件并存入File数组中,然后通过循环使用file.delet()方法逐一删除。


仅提供代码的答案是不被鼓励的,因为它们没有解释如何解决问题。请更新您的答案,解释它如何改进其他已被接受和赞同的答案,并删除代码中的多个无效文本实例(“在此输入代码”)。请查看如何撰写好的答案 - FluffyKitten

2

如果你使用的是Android Studio 4.4.2版本

getCacheDir().delete();

2
无法工作。根据文档:“如果此路径名表示目录,则必须清空该目录才能删除。” - hej2010

1
将这段代码放在MainActivityonStop()方法中。
@Override
protected void onStop() {
    super.onStop();
    AppUtils.deleteCache(getApplicationContext());
}

public class AppUtils {
    public static void deleteCache(Context context) {
        try {
            File dir = context.getCacheDir();
            deleteDir(dir);
        } catch (Exception e) {}
    }

    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;
                }
            }
            return dir.delete();
        } else if(dir!= null && dir.isFile()) {
            return dir.delete();
        } else {
            return false;
        }
    }
}

0
使用 Kotlin:仅删除内容:
for (file:File in context?.cacheDir?.listFiles()!!){
             file.delete()
         }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接