【问题标题】:WebView: clear service worker cache programmaticallyWebView:以编程方式清除服务工作者缓存
【发布时间】:2017-11-21 13:41:49
【问题描述】:

为了给用户提供一种快速清除缓存的方法,我使用了以下附加到清除缓存按钮的函数(基于thisthis):

static void clearAppCache(Context context) {
    try {
        File dir = context.getCacheDir();
        deleteDir(dir);
    } catch (Exception e) {
        // TODO: handle exception
    }
}

private static boolean deleteDir(File dir) {
    if (dir != null && dir.isDirectory()) {
        String[] children = dir.list();
        for (String aChildren : children) {
            boolean success = deleteDir(new File(dir, aChildren));
            if (!success) {
                return false;
            }
        }
        return dir.delete();
    } else if (dir!= null && dir.isFile()) {
        return dir.delete();
    } else {
        return false;
    }
}

我也在用相同的缓存路径设置我的 WebView,如下:

WebSettings webSettings = mWebView.getSettings();
webSettings.setAppCacheEnabled(true);
String cachePath = getApplicationContext().getCacheDir().getAbsolutePath();
webSettings.setAppCachePath(cachePath);

我的理论是调用clearAppCache() 也会清除 WebView 的缓存,因为它所做的只是清除我为 WebView 设置的同一个缓存文件夹。

但由于我的 WebView 现在正在加载一个使用 service worker 的页面,我发现这似乎并没有清除 service worker 缓存.我收到一位用户的报告,要真正清除服务人员的东西,他们必须手动清除以下文件夹的内容(在他们的根设备上):

/data/data/com.example.myapp/app_webview/Cache/

基于this post,我尝试将以下行添加到我的clearAppCache() 函数中:

WebStorage.getInstance().deleteAllData();

但这似乎仍然没有清除服务工作者缓存的效果。

有什么想法吗?是的,我知道可以使用 javascript 清除 service worker 缓存(请参阅上面链接的帖子),但我想要一种直接从 Android 执行此操作的方法。

【问题讨论】:

    标签: android caching webview service-worker


    【解决方案1】:

    我现在找到了删除服务工作者缓存的方法。我的数据目录在:

    /data/user/0/com.app.package
    

    然后在里面是:

    /cache
        /http
        /org.chromium.android_webview
        /WebView
    /code_cache
    /files
    /shared_prefs
    /app_webview
        /webview_data.lock
        /Web Data
        /Web Data-journal
        /metrics_guid
        /Cookies
        /Cookies-journal
        /GPUCache
        /Service Worker
        /QuotaManager
        /QuotaManager-journal
        /databases
    /app_textures
    /app_download_internal
    /databases
    /shaders
    

    请注意app_webview 中存在Service Worker 子目录,这有点赠品。

    所以,要清除 Service Worker 缓存,您似乎只需要删除该子目录即可:

    File dataDir = context.getDataDir(); // or see https://stackoverflow.com/a/19630415/4070848 for older Android versions
    File serviceWorkerDir = new File(dataDir.getPath() + "/app_webview/Service Worker/");
    deleteDir(serviceWorkerDir); // function defined in original post
    

    或者,更残酷的是,您似乎可以删除整个 app_webview 子文件夹及其中的所有内容:

    File dataDir = context.getDataDir(); // or see https://stackoverflow.com/a/19630415/4070848 for older Android versions
    File appWebViewDir = new File(dataDir.getPath() + "/app_webview/");
    deleteDir(appWebViewDir); // function defined in original post
    

    仍然让我感到困惑的是,尽管将带有 webSettings.setAppCachePath(cachePath) 的 WebView 的缓存路径设置在缓存目录中(请参阅我的原始帖子),但 WebView 选择使用 app_webview 进行服务工作者缓存。也许它使用缓存目录进行传统的 http 缓存,并选择自己的位置 (app_webview) 进行服务工作者缓存?但这似乎仍然不对。此外,如前所述,一位用户报告app_webview 中存在Cache 子目录,并且他们在不支持服务工作者的KitKat(Android 4.4)上......不知道为什么app_webview/Cache目录正在使用,而不是(或除了)cache。我根本没有app_webview/Cache

    【讨论】:

      【解决方案2】:

      我不熟悉 AndroidWebView 交互。但是假设您可以从本地页面的上下文中运行 JavaScript,以下代码应该会清除您的来源的缓存存储 API 中的所有内容:

      async function clearAllCaches() {
        const allCaches = await caches.keys();
        for (const cache of allCaches) {
          caches.delete(cache);
        }
      }
      

      如果您可以控制为您的 HTML 提供服务的远程网络服务器,并且您知道您的用户将拥有基于 Chrome 61+ 的 WebView,则使用 Clear-Site-Data header 是另一种选择。

      【讨论】:

      • Clear-Site-Data 标头是一个有趣的选项@JeffPosnick,因为它允许从主机(我确实控制)对客户端缓存进行一些控制。但是,我不清楚如何设置它...我习惯于在.htaccess 文件中设置标题,例如Header set Cache-Control "no-store, no-cache, must-revalidate, max-age=0",但Clear-Site-Data 标题是一个 JSON 字符串 (w3.org/TR/clear-site-data),它已经包括像 "[ 这样不符合标准 .htaccess 语法并导致问题的字符......有什么想法吗?
      • 我不经常使用.htaccess 文件,但一般来说, `` 是用于转义字符的习惯。那么... \" 和 \[ 工作吗?
      • 天啊!是的,它似乎...标题出现在 DevTools 的响应中。但是实际上会发生什么,例如我的头 html 页面在响应中带有这样的标题(指定所有“缓存”、“cookies”、“存储”、“executionContexts”)......浏览器做什么?只清除一次,然后继续加载(并将内容存储在缓存中,包括服务工作者缓存),并且在随后的刷新中它不会再次清除这些内容?
      • 我认为w3c.github.io/webappsec-clear-site-data/#fetch-integration 是权威答案,尽管该文档的当前状态暗示实施可能会发生变化。
      • 我应该注意到我上面包含的 w3c 参考是一个旧版本......以下是更新的:w3c.github.io/webappsec-clear-site-data 并且标题格式是一个(更明智的)逗号分隔列表(而不是 JSON 字符串),例如:Clear-Site-Data: "cache", "cookies", "storage", "executionContexts"。尽管到目前为止进行了一些尝试,但我仍然不知道如何完成这项工作......我会继续努力......
      猜你喜欢
      • 2019-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多