原文https://blog.csdn.net/zxg_1991/article/details/80008685
1 介绍
首先介绍几篇不错的文章,很多简介就不说了,可以去看一下这几篇文正,写的很详细,我也是在做项目的过程中的学习这几篇文章,不过运用的场景可能不太相同,所以我把我的场景写了下来。
Glide是Google官方推荐的图片加载库,既然是Google官方推荐,性能和效率自然不会差,这也是我平常会选择Glide作为首选图片加载库的原因。在实际开发中,有时候我们需要在预览图片的同时,还需要提供图片保存到本地功能,如果你项目使用的是Glide,那么结合Glide实现下载功能就轻而易举了,Glide会优先从缓存中查找图片资源,有缓存直接获取缓存图片,无缓存则从网络下载,简单高效。
这里面实现了对图片的下载,还有实现了在控件中加载图片,直接把图片异步的加载到image控件里,这两种场景是最多的。
2 使用场景
当前项目需要在VR场景的天空盒里加载服务器图片,由于项目限制,需要本地下载所有图片,根据不同VR场景来显示。
- 需要下载大量图片
- 需要判断图片是否下载完成,如果未完成优先加载部分图片
3 Glide下载图片
Glide下载图片到本地有几种方式:
- downloadOnly方法,同步下载,需要自己创建线程来执行下载过程
File file = Glide.with(context)
.load(url)
.downloadOnly(width, height)
.get();
FileUtil.copy(file, target);
下载文件到缓存路径,/data/data/包名/image_manager_disk_cache 这样的路径,可以将缓存文件复制到需要的地方,例如sdcard中。width,height是下载的图片宽和高,不过在改变尺寸后仍然下载的是原图,没有按照预期的宽高返回,个人认为是get()函数不支持预定义宽高。
附一个文件拷贝函数。
/**
* 复制文件
*
* @param source 输入文件
* @param target 输出文件
*/
public static void copy(File source, File target) {
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
try {
fileInputStream = new FileInputStream(source);
fileOutputStream = new FileOutputStream(target);
byte[] buffer = new byte[1024];
while (fileInputStream.read(buffer) > 0) {
fileOutputStream.write(buffer);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (fileInputStream != null) {
fileInputStream.close();
}
if (fileOutputStream != null) {
fileOutputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
- asBitmap()方法,同步下载,直接下载图片加载到Bitmap中。
Bitmap bitmap = Glide.with(context)
.load(url)
.asBitmap()
.into(width, height)
.get();
同步执行,得到返回的bitmap,width和height是加载图片的宽高,可以自定义设置,得到该大小的图片。虽然通过width和height可以控制加载图片的大小,但是下载的仍然是原图,不会改变下载过程的耗时,比如说into(500,500)和(1000,1000),虽然最后得到的图片大小差了很多,但是下载时间没有产生这个量级的差异。
- asBitmap().toBytes() 有些情况需要保存获取到的自定义大小图片,可以使用toBytes()函数。
byte[] bytes = Glide.with(context)
.load(url)
.asBitmap()
.toBytes()
.into(width, height)
.get();
FileUtil.copy(target, bytes);
/**
* 复制文件
* @param filename 文件名
* @param bytes 数据
*/
public static void copy(String filename, byte[] bytes) {
try {
//如果手机已插入sd卡,且app具有读写sd卡的权限
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
FileOutputStream output = null;
output = new FileOutputStream(filename);
output.write(bytes);
Log.i(TAG, copy: success," + filename);
output.close();
} else {
Log.i(TAG, "copy:fail, " + filename);
}
} catch (IOException e) {
e.printStackTrace();
}
}
同步执行,得到自定义width和height大小的图片byte,可以保存到文件或者进行其他处理。
- SimpleTarget,异步下载,前面几个方法需要在线程中执行,否则会阻塞主线程,通过SimpleTarget是先异步下载
Glide.with(context)
.load(url)
.asBitmap()
.toBytes()
.into(new SimpleTarget<byte[]>(width, height) {
@Override
public void onResourceReady(byte[] bytes, GlideAnimation<? super byte[]> glideAnimation) {
// 下载成功回调函数
// 数据处理方法,保存bytes到文件
FileUtil.copy(file, bytes);
}
@Override
public void onLoadFailed(Exception e, Drawable errorDrawable) {
// 下载失败回调
}
});
Glide通过SimpleTarget类实现异步下载,所以必须在主线程中使用,在其他线程调用会出现异常,SimpleTarget可以为多种类型,通过前面的asBitmap().toBytes()函数控制,width和height是图片自定义加载的宽高。