你如何理解这个注释
注意:如果更频繁地访问缓存图像,例如在图像库应用程序中,ContentProvider 可能是存储缓存图像的更合适的位置。
在这篇培训文章中https://developer.android.com/training/displaying-bitmaps/cache-bitmap.html?由于我无法获取Bitmap
或File
来自Cursor
,如何通过 ContentProvider 缓存位图?
你如何理解这个注释
注意:如果更频繁地访问缓存图像,例如在图像库应用程序中,ContentProvider 可能是存储缓存图像的更合适的位置。
在这篇培训文章中https://developer.android.com/training/displaying-bitmaps/cache-bitmap.html?由于我无法获取Bitmap
或File
来自Cursor
,如何通过 ContentProvider 缓存位图?
您实际上可以使用 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 作为磁盘缓存,但我确实相信这就是该注释所指的内容。
我强烈建议使用该https://github.com/nostra13/Android-Universal-Image-Loader
库来下载和缓存图像
您可以将库作为 JAR 文件下载,该文件可以轻松包含到任何 Android 项目中
来自官方页面的功能:
->多线程图像加载
-> 可以广泛调整 ImageLoader 的配置(线程池大小、HTTP 选项、内存和磁盘缓存、显示图像选项等)
->在内存和/或设备的文件系统(或 SD 卡)中缓存图像的可能性
->“听”加载过程的可能性
-> 可以使用单独的选项自定义每个显示图像调用小部件支持
提到的段落强调,与其在请求时查找和处理所有数据,不如实现一个单独的内容模型(或使用内置的),它默默地索引数据并保存预览(图像的缩略图,或前 2 行文本文件等)在磁盘上。这实现了:
使用较少的 RAM,因为预处理的数据已在磁盘上准备好。例如,一个真的很长List view
不需要Drawable
在内存中一次加载所有预览。它可能只是在滚动时从内容模型/提供者小批量请求缓存数据到内存缓存。
节省 CPU。内存中的缓存是易失性的,需要再次重新创建,而磁盘缓存使我们免于这种额外的处理。