原文https://blog.csdn.net/zxg_1991/article/details/80008685
1 介紹
首先介紹幾篇不錯的文章,很多簡介就不說了,可以去看一下這幾篇文正,寫的很詳細,我也是在做項目的過程中的學(xué)習這幾篇文章,不過運用的場景可能不太相同,所以我把我的場景寫了下來。
Glide是Google官方推薦的圖片加載庫,既然是Google官方推薦,性能和效率自然不會差,這也是我平常會選擇Glide作為首選圖片加載庫的原因。在實際開發(fā)中,有時候我們需要在預(yù)覽圖片的同時,還需要提供圖片保存到本地功能,如果你項目使用的是Glide,那么結(jié)合Glide實現(xiàn)下載功能就輕而易舉了,Glide會優(yōu)先從緩存中查找圖片資源,有緩存直接獲取緩存圖片,無緩存則從網(wǎng)絡(luò)下載,簡單高效。
這里面實現(xiàn)了對圖片的下載,還有實現(xiàn)了在控件中加載圖片,直接把圖片異步的加載到image控件里,這兩種場景是最多的。
2 使用場景
當前項目需要在VR場景的天空盒里加載服務(wù)器圖片,由于項目限制,需要本地下載所有圖片,根據(jù)不同VR場景來顯示。
- 需要下載大量圖片
- 需要判斷圖片是否下載完成,如果未完成優(yōu)先加載部分圖片
3 Glide下載圖片
Glide下載圖片到本地有幾種方式:
- downloadOnly方法,同步下載,需要自己創(chuàng)建線程來執(zhí)行下載過程
File file = Glide.with(context)
.load(url)
.downloadOnly(width, height)
.get();
FileUtil.copy(file, target);
下載文件到緩存路徑,/data/data/包名/image_manager_disk_cache 這樣的路徑,可以將緩存文件復(fù)制到需要的地方,例如sdcard中。width,height是下載的圖片寬和高,不過在改變尺寸后仍然下載的是原圖,沒有按照預(yù)期的寬高返回,個人認為是get()函數(shù)不支持預(yù)定義寬高。
附一個文件拷貝函數(shù)。
/**
* 復(fù)制文件
*
* @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();
同步執(zhí)行,得到返回的bitmap,width和height是加載圖片的寬高,可以自定義設(shè)置,得到該大小的圖片。雖然通過width和height可以控制加載圖片的大小,但是下載的仍然是原圖,不會改變下載過程的耗時,比如說into(500,500)和(1000,1000),雖然最后得到的圖片大小差了很多,但是下載時間沒有產(chǎn)生這個量級的差異。
- asBitmap().toBytes() 有些情況需要保存獲取到的自定義大小圖片,可以使用toBytes()函數(shù)。
byte[] bytes = Glide.with(context)
.load(url)
.asBitmap()
.toBytes()
.into(width, height)
.get();
FileUtil.copy(target, bytes);
/**
* 復(fù)制文件
* @param filename 文件名
* @param bytes 數(shù)據(jù)
*/
public static void copy(String filename, byte[] bytes) {
try {
//如果手機已插入sd卡,且app具有讀寫sd卡的權(quán)限
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();
}
}
同步執(zhí)行,得到自定義width和height大小的圖片byte,可以保存到文件或者進行其他處理。
- SimpleTarget,異步下載,前面幾個方法需要在線程中執(zhí)行,否則會阻塞主線程,通過SimpleTarget是先異步下載
Glide.with(context)
.load(url)
.asBitmap()
.toBytes()
.into(new SimpleTarget<byte[]>(width, height) {
@Override
public void onResourceReady(byte[] bytes, GlideAnimation<? super byte[]> glideAnimation) {
// 下載成功回調(diào)函數(shù)
// 數(shù)據(jù)處理方法,保存bytes到文件
FileUtil.copy(file, bytes);
}
@Override
public void onLoadFailed(Exception e, Drawable errorDrawable) {
// 下載失敗回調(diào)
}
});
Glide通過SimpleTarget類實現(xiàn)異步下載,所以必須在主線程中使用,在其他線程調(diào)用會出現(xiàn)異常,SimpleTarget可以為多種類型,通過前面的asBitmap().toBytes()函數(shù)控制,width和height是圖片自定義加載的寬高。