你如何理解这个笔记
注意:ContentProvider可能是更适合存储的地方 如果更频繁地访问它们,则缓存图像,例如在 图片库应用程序。
在这篇培训文章https://developer.android.com/training/displaying-bitmaps/cache-bitmap.html中?由于我无法从Bitmap
获取File
或Cursor
,如何通过ContentProvider缓存位图?
答案 0 :(得分:3)
您实际上可以使用ContentProvider读取和写入文件。
要在您自己的ContentProvider中支持此功能,您必须在 getStreamTypes()方法中包含受支持的文件MIME类型。检查Android ContentProvider tutorial here for more info的MIME类型部分。
您还需要实现 openFile(Uri uri, String mode) method ,您可以根据提供给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);
}
您可以使用此处的任何逻辑来选择文件目录。此代码只使用应用程序文件目录,但出于Bitmap缓存的目的,这应该使用临时缓存目录。
最后,访问ContentProvider文件数据的代码应如下所示:
ContentResolver cr = getContext().getContentResolver();
InputStream inputStream = cr.openInputStream(uri);
或者,您可以使用 ContentResolver.openOutputStream(uri)将文件数据写入ContentProvider。
Bitmap缓存教程需要进行相当多的修改才能将ContentProvider用作磁盘缓存,但我确实认为这是该笔记所指的内容。
答案 1 :(得分:1)
我强烈建议您使用https://github.com/nostra13/Android-Universal-Image-Loader
库来下载和缓存图片
您可以将该库下载为可轻松包含在任何Android项目中的JAR文件
官方网页的功能:
- >多线程图片加载
- >可以广泛调整ImageLoader的配置(线程池大小,HTTP选项,内存和光盘缓存,显示图像选项等)
- >图像缓存在内存和/或设备的文件系统(或SD卡)上的可能性
- >“倾听”加载过程的可能性
- >可以使用单独的选项Widget支持自定义每个显示图像调用
答案 2 :(得分:0)
上述段落强调,不是在请求时查找和处理所有数据,而是最好实现一个单独的内容模型(或使用内置模型),它静默地索引数据并保存预览(图像的缩略图,或者磁盘上的前两行文本文件等)。这实现了:
使用较少的RAM,因为预处理的数据已在磁盘上准备就绪。例如,一个非常长的List view
无需在内存中同时将所有预览加载为Drawable
。当它滚动时,它可能只是要求内容模型/提供者以小批量向内存缓存中提供缓存数据。
节省CPU。内存缓存是易失性的,需要重新进行重新创建,而在磁盘缓存上可以使我们免于这种额外的处理。