android - Glide 4.X:DataFetcher - 尝试从 ZIP 文件加载图片
问题描述
我必须解密图像并将其加载到 ImageViewGlide
的约束条件下,不要将解密的图像保存在磁盘上。据我所知Glide
,有机会使用DataFetcher
. 作为DataFetcher
用法示例,我想先从zip
文件中加载图像。
A 已阅读编写自定义 ModelLoader并在作者的存储库的基础上创建了自己的存储库,并尝试重写代码以用于在方法内解压缩单个图片zip
文件DataFetcher.loadData
并将其加载到ImageView
.
public class FileDataFetcher implements DataFetcher<InputStream> {
private final FileEnveloper fileEnveloper;
FileDataFetcher(FileEnveloper fileEnveloper) {
this.fileEnveloper = fileEnveloper;
}
@Override
public void loadData(@NonNull Priority priority, DataCallback<? super InputStream> callback) {
try {
unzip(); //Works fine!
FileInputStream fin = new FileInputStream(fileEnveloper.getFile());
ZipInputStream zin = new ZipInputStream(fin);
callback.onDataReady(zin);
} catch (IOException e) {
e.printStackTrace();
callback.onLoadFailed(e);
}
}
@Override
public void cleanup() {
// Intentionally empty only because we're not opening an InputStream or another I/O resource!
}
@Override
public void cancel() {
// Intentionally empty.
}
@NonNull
@Override
public Class<InputStream> getDataClass() {
return InputStream.class;
}
@NonNull
@Override
public DataSource getDataSource() {
return DataSource.LOCAL;
}
private void unzip() throws IOException {
String location = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator ;
FileInputStream fin = new FileInputStream(fileEnveloper.getFile());
ZipInputStream zin = new ZipInputStream(fin);
ZipEntry ze;
while ((ze = zin.getNextEntry()) != null) {
if (ze.isDirectory()) {
File dir = new File(location + ze.getName());
if (!dir.exists() || !dir.isDirectory())
dir.mkdirs();
} else {
FileOutputStream fout = new FileOutputStream(location + ze.getName());
byte[] buffer = new byte[1024];
int read = 0;
while ((read = zin.read(buffer)) != -1) {
fout.write(buffer, 0, read);
}
zin.closeEntry();
fout.close();
}
}
zin.close();
}
}
方法unzip()
工作正常,所需的解压缩图片出现在磁盘上,但callback.onDataReady(zin)
会导致堆栈跟踪:
2019-12-22 13:57:22.605 28803-28803/judds.github.com.base64modelloaderexample W/Glide: Load failed for judds.github.com.base64modelloaderexample.FileEnveloper@2d3a6e1c with size [720x1257]
class com.bumptech.glide.load.engine.GlideException: Failed to load resource
Cause (1 of 1): class com.bumptech.glide.load.engine.GlideException: Failed LoadPath{ZipInputStream->Object->Drawable}, LOCAL
Cause (1 of 3): class com.bumptech.glide.load.engine.GlideException: Failed DecodePath{ZipInputStream->GifDrawable->Drawable}
Cause (2 of 3): class com.bumptech.glide.load.engine.GlideException: Failed DecodePath{ZipInputStream->Bitmap->Drawable}
Cause (3 of 3): class com.bumptech.glide.load.engine.GlideException: Failed DecodePath{ZipInputStream->BitmapDrawable->Drawable}
我想原因不在于withGlide
的错误用法,而在于ZipInputStream
with的错误用法Glide
。有人知道应该怎么做吗?
解决方案
为了让它工作(对于zip
-archive 中的单个文件),我们必须ZipInputStream
在初始位置设置zin.getNextEntry()
如下:
@Override
public void loadData(@NonNull Priority priority, DataCallback<? super InputStream> callback) {
try {
unzip(); //Works fine!
FileInputStream fin = new FileInputStream(fileEnveloper.getFile());
ZipInputStream zin = new ZipInputStream(fin);
zin.getNextEntry();//Essential!!!
callback.onDataReady(zin);
} catch (IOException e) {
e.printStackTrace();
callback.onLoadFailed(e);
}
}
推荐阅读
- c - 如何确定指针是否在rodata中
- python - RuntimeError: Found dtype Long but expected Float: 使用标准时
- git - git 将两个文件合并为一个文件
- python - 前 n 位可被 n 整除的 10 位数字
- python - 将硬球装在盒子里
- c++ - 会员运营商和doxygen难度
- java - 移动后保留数据
- python - 使用 python 脚本(数据库 URI)连接到 postgresql,但将“conn”检测为字符串
- spss - 为相同的变量值添加相同的数据(即 ID)
- sql - 从 TSQL 中的表列表中检查表是否为空