You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GetCacheDir()与系统清除缓存按钮的差异及缓存无法清零问题排查

解决Xamarin.Forms Android应用缓存清理残留问题及API说明

一、为什么清理后仍有20KB缓存?

这些残留缓存大概率来自你未清理的其他系统缓存目录,常见的有以下几类:

  • Code Cache目录:Android 6.0(API 23)及以上版本会在此目录存放ART即时编译的缓存文件,系统会将其计入应用缓存大小。通过Context.GetCodeCacheDir()获取该目录,需要一并删除其中所有文件和子目录。
  • 多外部存储缓存目录:如果设备存在多个外部存储分区(如内置共享存储+外置SD卡),GetExternalCacheDir()仅返回第一个外部缓存目录,而Context.GetExternalCacheDirs()会返回所有可用的外部缓存目录,这些目录下的缓存文件也会被系统统计,需要遍历清理每一个。
  • WebView专属缓存:如果应用使用了WebView,它的缓存除部分存于getCacheDir()下,还可能有独立的缓存目录,仅删除目录可能无法完全清理,需调用WebView的ClearCache(true)方法彻底清理。

另外,系统设置的缓存大小显示一般不存在bug,但存在统计延迟:删除文件后,系统需要一段时间重新扫描计算缓存大小,可等待几分钟或重启应用后再查看。

二、getCacheDir()与GetExternalCacheDir()的差异及正确用法

这两个方法均用于获取应用专属缓存目录,但核心差异在于存储位置和访问限制:

1. Context.GetCacheDir()(内部缓存目录)

  • 存储路径:设备内部存储的/data/data/你的应用包名/cache/
  • 核心特点:
    • 应用私有目录,其他应用无法访问,无需申请存储权限
    • 设备内部存储不足时,系统会自动删除该目录文件释放空间
    • 卸载应用时,该目录会被自动删除
  • 适用场景:存储临时、无需长期保留的小文件,如网络请求临时缓存、图片缩略图等。

2. Context.GetExternalCacheDir()(外部缓存目录)

  • 存储路径:外部存储的/Android/data/你的应用包名/cache/(外部存储可指设备内置共享存储或外置SD卡)
  • 核心特点:
    • Android 4.4(API 19)及以上版本无需申请WRITE_EXTERNAL_STORAGE权限即可访问;低于API 19版本需申请权限
    • 外部存储不足时,系统可能删除该目录文件,但优先级低于内部缓存
    • 卸载应用时,该目录会被自动删除
  • 适用场景:存储较大的临时文件如下载安装包、高清图片缓存等,避免占用内部存储。

三、实现与系统「清除缓存」一致效果的代码示例

在Xamarin.Forms的Android项目中,可通过依赖服务实现完整清理逻辑:

using System.IO;
using Android.Content;
using Xamarin.Forms;

[assembly: Dependency(typeof(CacheCleaner))]
namespace MyXFApp.Droid
{
    public class CacheCleaner : ICacheCleaner
    {
        public void ClearAllCache()
        {
            var context = Android.App.Application.Context;
            
            // 清理内部缓存目录
            DeleteDirectory(context.CacheDir);
            
            // 清理Code Cache目录(API 23+)
            if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.M)
            {
                DeleteDirectory(context.CodeCacheDir);
            }
            
            // 清理所有外部缓存目录
            var externalCacheDirs = context.GetExternalCacheDirs();
            foreach (var dir in externalCacheDirs)
            {
                if (dir != null)
                {
                    DeleteDirectory(dir);
                }
            }
            
            // 清理WebView缓存(若应用使用WebView)
            Android.Webkit.WebView.ClearCache(true);
        }

        private void DeleteDirectory(Java.IO.File directory)
        {
            if (!directory.Exists) return;
            
            foreach (var file in directory.ListFiles())
            {
                if (file.IsDirectory)
                {
                    DeleteDirectory(file);
                }
                else
                {
                    file.Delete();
                }
            }
            
            directory.Delete();
        }
    }
}

// 共享项目中定义接口
public interface ICacheCleaner
{
    void ClearAllCache();
}

在共享项目中调用清理逻辑:

DependencyService.Get<ICacheCleaner>().ClearAllCache();

内容的提问来源于stack exchange,提问作者Alexandre Mirabel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 05:46:08