我的系列文章
Android圖片加載框架:Glide的常用用法|SquirrelNote
Android圖片加載框架:Glide源碼解析|SquirrelNote
前言
現(xiàn)在Android上的圖片加載框架非常成熟,從最早的圖片加載框架UniversalImageLoader,到后來(lái)Google推出的Volley,再到后來(lái)的Glide和Picasso循诉,當(dāng)然還有Facebook的Fresco。每一個(gè)都非常穩(wěn)定嫌术,功能也都十分強(qiáng)大嗽冒。但是它們的使用場(chǎng)景基本都是重合的猖任,也就是說(shuō)我們基本只需要選擇其中一個(gè)來(lái)進(jìn)行學(xué)習(xí)和使用就足夠了就珠,每一個(gè)框架都嘗試去掌握的話則有些浪費(fèi)時(shí)間寇壳。
框架的選擇
從易用性上來(lái)講醒颖,Glide和Picasso應(yīng)該都是完勝其他框架的妻怎,這兩個(gè)框架都簡(jiǎn)單好用,大多數(shù)情況下加載圖片都是一行代碼就能解決的.
Glide和Picasso比較
Picasso所能實(shí)現(xiàn)的功能泞歉,Glide都能做逼侦,區(qū)別是所需的設(shè)置不同。Picasso比Glide更加簡(jiǎn)潔輕量腰耙,Glide比Picasso功能更為豐富榛丢。Glide的好處是大型的圖片流,比如gif動(dòng)態(tài)圖挺庞、Video晰赞,如果是做美拍、愛(ài)拍這種視頻類應(yīng)用选侨,建議使用掖鱼。
如果項(xiàng)目中網(wǎng)絡(luò)請(qǐng)求本身用的是Square公司的全家桶,比如OkHttp或者retrofit(本質(zhì)還是OkHttp),那么建議搭配Picasso一起使用援制,兼容性可能會(huì)更好些戏挡,占用體積也會(huì)少些。
經(jīng)過(guò)多方面對(duì)比之后晨仑,我還是決定選擇了Glide來(lái)進(jìn)行研究褐墅,并且這也是Google官方推薦的圖片加載框架。
下面對(duì)Glide常用用法進(jìn)行詳細(xì)介紹:
- Glide的用法
- 占位圖功能
- 指定圖片格式(支持加載Gif圖片)
Glide的用法
GitHub開(kāi)源框架:https://github.com/bumptech/glide
目前洪己,Glide最新的穩(wěn)定版本是3.7.0妥凳,雖然4.0已經(jīng)推出RC版了,但是暫時(shí)問(wèn)題還比較多答捕。
新建一個(gè)GlideDemo項(xiàng)目猾封,然后在app/build.gradle文件當(dāng)中添加如下依賴:
compile 'com.github.bumptech.glide:glide:3.7.0'
注意:使用4.0版本出容易bug
另外,Glide中需要用到網(wǎng)絡(luò)功能噪珊,因此要在AndroidManifest.xml中聲明一下網(wǎng)絡(luò)權(quán)限:
<uses-permission android:name="android.permission.INTERNET" />
加載圖片
使用Glide如何加載圖片晌缘,如下tomcat服務(wù)器上的照片:
http://192.168.6.102:8080/songshu.jpg
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.glidedemo.activity.GlideTestActivity">
<Button
android:id="@+id/btn_glide"
android:text="使用Glide顯示加載圖片"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<ImageView
android:id="@+id/iv_glide"
android:layout_gravity="center"
android:layout_width="100dp"
android:layout_height="100dp"/>
</LinearLayout>
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_glide_test);
mBtn_glide = (Button) findViewById(R.id.btn_glide);
mImageView = (ImageView) findViewById(R.id.iv_glide);
//設(shè)置點(diǎn)擊監(jiān)聽(tīng)
mBtn_glide.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
loadImage();
}
});
}
private void loadImage() {
String url="http://192.168.6.102:8080/songshu.jpg";
Glide.with(this).load(url).into(mImageView);
}
核心代碼只有一行:
Glide.with(this).load(url).into(mImageView);
這一行代碼可以做很多事情齐莲,加載網(wǎng)絡(luò)上的圖片、加載手機(jī)本地的圖片磷箕、加載應(yīng)用資源中的圖片等等选酗。
解析這一行代碼:
調(diào)用Glide.with()方法用于創(chuàng)建一個(gè)加載圖片的實(shí)例。with()方法可以接收Context岳枷、Activity或者Fragment類型的參數(shù)芒填,即可以直接傳this。如果調(diào)用的地方不在Activity空繁、Fragment殿衰,可以獲取當(dāng)前應(yīng)用程序的ApplicationContext,傳入到with()方法當(dāng)中。
注意:with()方法中傳入的實(shí)例會(huì)決定Glide加載圖片的生命周期盛泡,如果傳入的是Activity或者Fragment的實(shí)例闷祥,那么當(dāng)這個(gè)Activity或Fragment被銷毀的時(shí)候,圖片加載也會(huì)停止傲诵。如果傳入的是ApplicationContext凯砍,那么只有當(dāng)應(yīng)用程序被殺掉的時(shí)候,圖片加載才會(huì)停止拴竹。
Glide支持加載各種各樣的圖片資源悟衩,包括網(wǎng)絡(luò)圖片、本地圖片栓拜、應(yīng)用資源座泳、二進(jìn)制流、Uri對(duì)象等等幕与。load()方法有很多個(gè)方法重載挑势,如下:
// 加載本地圖片
File file = new File(getExternalCacheDir() + "/image.jpg");
Glide.with(this).load(file).into(imageView);
// 加載應(yīng)用資源
int resource = R.drawable.image;
Glide.with(this).load(resource).into(imageView);
// 加載二進(jìn)制流
byte[] image = getImageBytes();
Glide.with(this).load(image).into(imageView);
// 加載Uri對(duì)象
Uri imageUri = getImageUri();
Glide.with(this).load(imageUri).into(imageView);
我們希望圖片顯示在哪個(gè)ImageView當(dāng)中,就把這個(gè)ImageView實(shí)例傳入into()方法里纽门,into()方法不僅能接收ImageView類型的參數(shù)薛耻,還支持很多豐富的用法(屬于高級(jí)技巧)。
Glide基本使用方式赏陵,三步:先with(),再load()饼齿,最后into()。熟記這三步蝙搔,就已經(jīng)入門了缕溉。
占位圖功能
因?yàn)閺木W(wǎng)絡(luò)上下載圖片需要時(shí)間,Glide提供了各種各樣的非常豐富的API支持吃型,其中就包括了占位圖功能证鸥。占位圖:指在圖片加載過(guò)程中,我們先顯示一張臨時(shí)圖片,等圖片加載出來(lái)了再替換成要加載的圖片枉层。
準(zhǔn)備好一張圖片loading.jpg,代碼如下:
Glide.with(this)
.load(url)
.placeholder(R.drawable.loading)
.into(mImageView);
如果再重新點(diǎn)擊按鈕泉褐,可能看不到占位圖效果。因?yàn)镚lide有非常強(qiáng)大的緩存機(jī)制鸟蜡,我們剛才加載那張必應(yīng)美圖的時(shí)候Glide自動(dòng)就已經(jīng)將它緩存下來(lái)了膜赃,下次加載的時(shí)候?qū)?huì)直接從緩存中讀取,不會(huì)再去網(wǎng)絡(luò)下載了揉忘,因而加載的速度非程快,所以占位圖可能根本來(lái)不及顯示泣矛。修改如下:
Glide.with(this)
.load(url)
.placeholder(R.drawable.loading)//占位圖
.diskCacheStrategy(DiskCacheStrategy.NONE)//禁用Glide的緩存功能
.into(mImageView);
顯示效果如下:
異常占位圖
如果因?yàn)槟承┊惓G闆r導(dǎo)致圖片加載失敗疲眷,比如說(shuō)手機(jī)網(wǎng)絡(luò)信號(hào)不好,這個(gè)時(shí)候就這張顯示異常占位圖您朽。
Glide.with(this)
.load(url)
.placeholder(R.drawable.loading)//占位圖
.error(R.drawable.error)//異常占位圖狂丝,比如手機(jī)沒(méi)網(wǎng)絡(luò),加載圖片失敗
.diskCacheStrategy(DiskCacheStrategy.NONE)//禁用Glide的緩存功能
.into(mImageView);
顯示效果如下:
以上就是Glide的占位圖功能。
指定圖片格式(支持加載Gif圖片)
相比Picasso,Picasso不支持加載Gif圖片虚倒。
把上面的url替換成一個(gè)gif圖片,效果如下圖所示:
Glide會(huì)自動(dòng)進(jìn)行判斷是普通圖片美侦,還是gif圖片产舞,并且可以正確地把它解析并展示出來(lái)魂奥。
但是如果我想指定圖片的格式該怎么辦呢?就比如說(shuō)易猫,我希望加載的這張圖必須是一張靜態(tài)圖片耻煤,我不需要Glide自動(dòng)幫我判斷它到底是靜圖還是GIF圖。
Glide.with(this)
.load(url)
.asBitmap()//只允許加載靜態(tài)圖片,不需要Glide去幫我們自動(dòng)進(jìn)行圖片格式判斷
//.asGif()//強(qiáng)制加載動(dòng)態(tài)圖片
.placeholder(R.drawable.loading)//占位圖
.error(R.drawable.error)//異常占位圖准颓,比如手機(jī)沒(méi)網(wǎng)絡(luò),加載圖片失敗
.diskCacheStrategy(DiskCacheStrategy.NONE)//禁用Glide的緩存功能
.into(mImageView);
調(diào)用了asBitmap()方法哈蝇,現(xiàn)在GIF圖就無(wú)法正常播放了,而是會(huì)在界面上顯示第一幀的圖片攘已。
同理炮赦,如果調(diào)用asGif()方法,強(qiáng)制加載動(dòng)態(tài)圖片样勃。如果傳入的是靜態(tài)圖片吠勘,結(jié)果會(huì)是加載失敗。
指定圖片大小
實(shí)際上峡眶,使用Glide在絕大多數(shù)情況下是不需要指定圖片大小的剧防。
我們平時(shí)在加載圖片的時(shí)候很容易會(huì)造成內(nèi)存浪費(fèi)。什么叫內(nèi)存浪費(fèi)呢辫樱?比如說(shuō)一張圖片的尺寸是1000 * 1000像素峭拘,但是我們界面上的ImageView可能只有200 * 200像素,這個(gè)時(shí)候如果你不對(duì)圖片進(jìn)行任何壓縮就直接讀取到內(nèi)存中,這就屬于內(nèi)存浪費(fèi)了鸡挠,因?yàn)槌绦蛑懈揪陀貌坏竭@么高像素的圖片辉饱。
關(guān)于圖片壓縮,我的另一篇文章:Android性能優(yōu)化:圖片的加載和圖片緩存技術(shù)|SquirrelNote
Glide會(huì)自動(dòng)判斷ImageView的大小拣展,然后只將這么大的圖片像素加載到內(nèi)存當(dāng)中鞋囊,幫助我們節(jié)省內(nèi)存。它的內(nèi)部實(shí)現(xiàn)原理瞎惫,就是上面一篇文章所介紹的技術(shù)溜腐,掌握了最基本的實(shí)現(xiàn)原理,我們也可以自己實(shí)現(xiàn)一套這樣的圖片壓縮機(jī)制瓜喇。
如果需要給圖片指定一個(gè)固定的大小的需求挺益,如下代碼:
Glide.with(this)
.load(url)
// .asBitmap()//只允許加載靜態(tài)圖片,不需要Glide去幫我們自動(dòng)進(jìn)行圖片格式判斷
.placeholder(R.drawable.loading)//占位圖
.error(R.drawable.error)//異常占位圖,比如手機(jī)沒(méi)網(wǎng)絡(luò),加載圖片失敗
.diskCacheStrategy(DiskCacheStrategy.NONE)//禁用Glide的緩存功能
.override(200,200)
.into(mImageView);
override()方法指定了一個(gè)圖片的尺寸乘寒。
以上是根據(jù)我的一些理解望众,做的總結(jié)分享,旨在拋磚引玉伞辛,希望有更多的志同道合的朋友一起討論學(xué)習(xí)烂翰,共同進(jìn)步!
參考文獻(xiàn):
http://blog.csdn.net/guolin_blog/article/details/53759439