Uri 指向已删除的文件,但仍显示在应用程序中,怎么办?

Uri points to deleted file but still displays in app, how?

在我的应用程序中,我使用相机拍照。然后使用它的 Uri 将这张图片加载到 ImageView 中,它看起来像这样:content://media/external/images/media/12345。我可以通过 querying the MediaStore 得到这个 Uri 的路径,它看起来像这样: /storage/emulated/0/DCIM/Camera/IMG_12345.jpg.

我现在从上面的那个路径手动删除图像。但是当我重新打开应用程序时,图像仍然存在并且可以在相同的 Uri 下访问。如果我再次查询 MediaStore,它会给我一个 CursorIndexOutOfBoundsException。所以文件不存在到MediaStore

那么这里发生了什么?如果我手动删除了该文件,那么该应用程序应该无法使用它。这个文件现在在哪里?有没有更好的删除图像的方法,以便从所有地方删除它们?

您应该阅读有关缓存的内容:https://en.wikipedia.org/wiki/Web_cache

第一次下载资源(如图片)时,浏览器(或大多数使用 built-in http 通信组件的应用程序)将该资源保存在 so-called 缓存。等下次再去读取资源的时候,发现已经缓存在本地了,不用再去网上加载了。

您无法完全控制该行为,但您可以使用 Cache-controlProxy headers 通过 HTTP 提供您的资源:https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

如果您想从缓存中删除该资源,那么,您必须清理浏览器缓存。通常,这可以在系统设置或浏览器设置中完成。

MediaStore 是可用文件的索引。与任何索引一样,它需要在文件系统发生更改时进行更新。而且,就像搜索引擎一样,主要有两种实现方式:

  • 有人告诉 MediaStore 扫描一些东西并将其添加到索引中
  • MediaStore 抓取文件系统

在您的情况下,使用文件管理器删除文件可能不会更新 MediaStore,部分原因是没有关于如何在删除内容时更新 MediaStore 的文档。这些文档专注于索引新文件,而不是删除已删除的文件。

Uri 似乎继续工作的原因是因为您的图像加载库(Glide,在您的情况下)。 Glide 有一个内存缓存,它会在可能的情况下使用缓存中的图像。