6

你如何理解这个注释

注意:如果更频繁地访问缓存图像,例如在图像库应用程序中,ContentProvider 可能是存储缓存图像的更合适的位置。

在这篇培训文章中https://developer.android.com/training/displaying-bitmaps/cache-bitmap.html?由于我无法获取BitmapFile来自Cursor,如何通过 ContentProvider 缓存位图?

4

3 回答 3

3

您实际上可以使用 ContentProvider 读取和写入文件。

要在您自己的 ContentProvider 中支持这一点,您必须在getStreamTypes()方法中包含您支持的 File MIME 类型。在此处查看 Android ContentProvider 教程的 MIME 类型部分以获取更多信息。

您还需要实现openFile(Uri uri, String mode) 方法,在该方法中,您将根据提供给 ContentResolver 的 Uri 实际选择文件目录和名称。这是该方法的示例实现:

  @Override
  public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
      File root = getContext().getFilesDir();
      File path = new File(root, uri.getEncodedPath());
      path.mkdirs();
      File file = new File(path, "file_"+uri.getLastPathSegment());

      int imode = 0;
      if (mode.contains("w")) {
        imode |= ParcelFileDescriptor.MODE_WRITE_ONLY;
        if (!file.exists()) {
          try {
            file.createNewFile();
          } catch (IOException e) {
            e.printStackTrace();
          }
        }
      }
      if (mode.contains("r"))
        imode |= ParcelFileDescriptor.MODE_READ_ONLY;
      if (mode.contains("+"))
        imode |= ParcelFileDescriptor.MODE_APPEND;

      return ParcelFileDescriptor.open(file, imode);
  }

您可以在此处使用您喜欢的任何逻辑来选择您的文件目录。此代码仅使用应用程序文件目录,但出于位图缓存的目的,这可能应该使用临时缓存目录。

最后,访问 ContentProvider 文件数据的代码应如下所示:

ContentResolver cr = getContext().getContentResolver();
InputStream inputStream = cr.openInputStream(uri);

或者,您可以使用ContentResolver.openOutputStream(uri)将文件数据写入 ContentProvider。

位图缓存教程需要进行相当多的修改才能使用 ContentProvider 作为磁盘缓存,但我确实相信这就是该注释所指的内容。

于 2013-02-22T23:43:56.817 回答
1

我强烈建议使用该https://github.com/nostra13/Android-Universal-Image-Loader库来下载和缓存图像

您可以将库作为 JAR 文件下载,该文件可以轻松包含到任何 Android 项目中

来自官方页面的功能:

->多线程图像加载

-> 可以广泛调整 ImageLoader 的配置(线程池大小、HTTP 选项、内存和磁盘缓存、显示图像选项等)

->在内存和/或设备的文件系统(或 SD 卡)中缓存图像的可能性

->“听”加载过程的可能性

-> 可以使用单独的选项自定义每个显示图像调用小部件支持

于 2012-11-08T10:15:53.823 回答
0

提到的段落强调,与其在请求时查找和处理所有数据,不如实现一个单独的内容模型(或使用内置的),它默默地索引数据并保存预览(图像的缩略图,或前 2 行文本文件等)在磁盘上。这实现了:

  1. 使用较少的 RAM,因为预处理的数据已在磁盘上准备好。例如,一个真的很长List view不需要Drawable在内存中一次加载所有预览。它可能只是在滚动时从内容模型/提供者小批量请求缓存数据到内存缓存。

  2. 节省 CPU。内存中的缓存是易失性的,需要再次重新创建,而磁盘缓存使我们免于这种额外的处理。

于 2012-11-08T10:39:24.250 回答