android图片加载库Glide的使用介绍
一:简介
在泰国举行的谷歌开发者论坛上,谷歌为我们介绍了一个名叫 Glide 的图片加载库,作者是bumptech。这个库被广泛的运用在google的开源项目中,包括2014年google I/O大会上发布的官方app。
赤城网站制作公司哪家好,找创新互联!从网页设计、网站建设、微信开发、APP开发、响应式网站开发等网站项目制作,到程序开发,运营维护。创新互联于2013年创立到现在10年的时间,我们拥有了丰富的建站经验和运维经验,来保证我们的工作的顺利进行。专注于网站建设就选创新互联。
https://github.com/bumptech/glide
二:使用
1 2 3 | dependencies { compile 'com.github.bumptech.glide:glide:3.7.0' } |
如何查看最新版本
http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22glide%22
三:使用方法及简介
http://mrfu.me/2016/02/27/Glide_Getting_Started/
四、清除缓存
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | /** * 清除缓存 * @param context */ public void clearCache( final Context context ){ clearMemoryCache( context ); new Thread( new Runnable() { @Override public void run() { clearDiskCache( context ); } }).start(); } /** * 清除内存缓存 * @param context */ public void clearMemoryCache( Context context ){ Glide.get( context ).clearMemory(); } /** * 清除磁盘缓存 * @param context */ public void clearDiskCache( Context context ){ Glide.get( context ).clearDiskCache(); } |
五、注意事项
5.1、在使用时需要给app添加联网权限,没有权限不会报错,但是图片加载不出来,很坑爹。
1 2 3 |
|
5.2、加载图片的方法要写在 UI 线程中,Glide会做异步处理。
六、使用方法总结
6.1 加载网络图片
1 2 3 | p_w_picpathView = (ImageView) findViewById( R.id.p_w_picpath ); String url = "http://img5.jpg" ; Glide.with( this ).load( url ).into( p_w_picpathView ) ; |
6.2 加载网络图片监听(下载完成后显示)
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | package lib.com.myapplication; import android.graphics.Bitmap; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.widget.ImageView; import com.bumptech.glide.Glide; import com.bumptech.glide.request.animation.GlideAnimation; import com.bumptech.glide.request.target.SimpleTarget; public class MainActivity extends AppCompatActivity { private ImageView p_w_picpathView ; String url = "http://img5.imgtn.bdimg.com/it/u=2941079711,2736454066&fm=11&gp=0.jpg" ; @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); p_w_picpathView = (ImageView) findViewById( R.id.p_w_picpath ); Glide.with( this ).load( url ).asBitmap().into( target ) ; } private SimpleTarget target = new SimpleTarget @Override public void onResourceReady(Bitmap bitmap, GlideAnimation glideAnimation) { //图片加载完成 p_w_picpathView.setImageBitmap(bitmap); } }; } |
特别注意 :.asBitmap() 一定要加,否则可能会出错
6.3 占位符 placeholder() 方法:在加载开始 -- 加载完成,这段时间显示的图片。如果加载失败,则最终显示占位符。
1 2 | p_w_picpathView = (ImageView) findViewById( R.id.p_w_picpath ); Glide.with( this ).load( url ).placeholder( R.drawable.user ).into( p_w_picpathView ) ; |
6.4 占位符 error() 方法:在加载失败的情况下,显示的图片。
1 2 | p_w_picpathView = (ImageView) findViewById( R.id.p_w_picpath ); Glide.with( this ).load( url ).placeholder( R.drawable.user ).error( R.drawable.default_error ).into( p_w_picpathView ) ; |
在加载开始--> 加载完成(失败),显示placeholder()图片; 如果加载失败,则显示error() 里面的图片。
6.5 加载 drawable 里面的图片
1 2 | p_w_picpathView = (ImageView) findViewById( R.id.p_w_picpath ); Glide.with( this ).load( R.drawable.icon ).asBitmap().into( p_w_picpathView ) ; |
6.6 加载 SD 卡里面的一张图片 1 load( String string)
1 2 3 4 | p_w_picpathView = (ImageView) findViewById( R.id.p_w_picpath ); //sd卡上的一张图片 String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/temp.jpg" ; Glide.with( this ).load( path ).into( p_w_picpathView ) ; |
6.7 加载 SD 卡里面的一张图片 2 load( File file )
1 2 3 4 5 | p_w_picpathView = (ImageView) findViewById( R.id.p_w_picpath ); //sd卡上的一张图片 String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/temp.jpg" ; File file = new File( path ) ; Glide.with( this ).load( file ).into( p_w_picpathView ) ; |
6.8 加载 SD 卡里面的一张图片 3 load( Uri uri )
1 2 3 4 5 | //sd卡上的一张图片 String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/temp.jpg" ; File file = new File( path ) ; Uri uri = Uri.fromFile( file ) ; Glide.with( this ).load( uri ).into( p_w_picpathView ) ; |
6.9 Glide.with() 生命周期控制
with(Context context). 使用Application上下文,Glide请求将不受Activity/Fragment生命周期控制。
with(Activity activity). 使用Activity作为上下文,Glide的请求会受到Activity生命周期控制。
with(FragmentActivity activity).Glide的请求会受到FragmentActivity生命周期控制。
with(android.app.Fragment fragment).Glide的请求会受到Fragment 生命周期控制。
with(android.support.v4.app.Fragment fragment).Glide的请求会受到Fragment生命周期控制。
请求会在onStop的时候自动暂停,
在onStart的时候重新启动,gif的动画也会在onStop的时候停止,以免在后台消耗电量。
6.10 加载优先级设置 priority()
枚举类 Priority 提供了几种优先级等级 ,
默认的是 : NORMAL
实例:
1 2 | Glide.with( this ).load( url2).priority(Priority.LOW ).into( p_w_picpathView2 ) ; Glide.with( this ).load( url3).priority(Priority.HIGH ).into( p_w_picpathView3 ) ; |
但是这里的优先级只是在加载的过程中起一个参考作用, 并不决定真正的加载顺序。
6.10 加载优先级设置 priority()
枚举类 Priority 提供了几种优先级等级 ,
默认的是 : NORMAL
实例:
1 2 | Glide.with( this ).load( url2).priority(Priority.LOW ).into( p_w_picpathView2 ) ; Glide.with( this ).load( url3).priority(Priority.HIGH ).into( p_w_picpathView3 ) ; |
但是这里的优先级只是在加载的过程中起一个参考作用, 并不决定真正的加载顺序。
6.11 缩略图的支持
(一) 先加载原图的十分之一作为缩略图,再加载原图
1 | Glide.with( thi ).load( url ).thumbnail( 0 .1f).into( p_w_picpathview ) ; |
(二)用本地的图片作为缩略图,然后再加载原图
1 2 3 4 | DrawableRequestBuilder .with( ThumbnailActivity. this ) .load(R.mipmap.ic_launcher); Glide.with( ThumbnailActivity. this ).load( ur2 ).thumbnail( thumbnailRequest ).into( p_w_picpathView2 ) ; |
6.12 加载 Gif 动图
1 2 | Glide.with( this ).load( url ).into( p_w_picpathView1 ) ; Glide.with( this ).load( url ).asGif().into( p_w_picpathView2 ) ; |
注意:如果把asGif 换成 asBitmap 则会显示一张静态图。
6.13 加载本地视频,相当于一张缩略图
1 2 3 | p_w_picpathView = (ImageView) findViewById( R.id.p_w_picpath_video ); String files = Environment.getExternalStorageDirectory().getAbsolutePath() + "/yueyu.mkv" ; Glide.with( this ).load( files ).into( p_w_picpathView ) ; |
(1)只能加载本地视频,网络视频无法加载。
(2)加载本地视频显示只是视频的第一帧图像,相当于一张缩略图。不能播放视频。
6.14 加载动画
.crossFade() 淡入淡出 , 也是默认动画
.crossFade( int duration ) 定义淡入淡出的时间间隔
.dontAnimate() 不使用任何动画
6.15 glide 内存缓存
glide 默认启用内存缓存,如果想要禁止内存缓存 ,使用 .skipMemoryCache( true )
七、自定义 GlideModule
自定义 GlideModule 的好处:
1、可以全局的改变 glide 的加载策略
2、可以自定义磁盘缓存目录
3、可以设置图片加载的质量
7.1 首先定义一个类实现 GlideModule
1 2 3 4 5 6 7 8 9 10 11 12 | public class SimpleGlideModule implements GlideModule { @Override public void applyOptions(Context context, GlideBuilder builder) { } @Override public void registerComponents(Context context, Glide glide) { } } |
可以看到重写了两个方法,applyOptions() , registerComponents() . 两个方法都没有返回值 。我们着重于第一个方法,重点研究 GlideBuilder 。
7.2 然后在 AndroidManifest.xml 去申明你写的 SimpleGlideModule
1 2 3 |
android:name= "app.zuil.com.glidedemo.util.SimpleGlideModule" android:value= "GlideModule" /> |
name是:包名 + 类名
7.3 GlideBuilder
.setMemoryCache(MemoryCache memoryCache)
.setBitmapPool(BitmapPool bitmapPool)
.setDiskCache(DiskCache.Factory diskCacheFactory)
.setDiskCacheService(ExecutorService service)
.setResizeService(ExecutorService service)
.setDecodeFormat(DecodeFormat decodeFormat)
可以看到 setBitmapPool() 是设置bitmap池的 ; setDecodeFormat() 是设置解码方式的 ; setDiskCache() 是设置磁盘缓存的 ;
7.4 DecodeFormat
Android里有两个方法去解析图片:ARGB8888
和RGB565
。第一个为每个像素采用4 byte表示,后面一个则用2 byte表示。ARG8888
有更高的图片质量,并且能够存储一个alpha通道。Glide默认使用低质量的RGB565
。你可以通过使用Glide module方法改变解析格式。
最后一个完整的自定义glideModule
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | public class SimpleGlideModule implements GlideModule { @Override public void applyOptions(Context context, GlideBuilder builder) { //定义缓存大小为100M int diskCacheSize = 100 * 1024 * 1024 ; //自定义缓存 路径 和 缓存大小 String diskCachePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/glideCache" ; //提高图片质量 builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888); //自定义磁盘缓存:这种缓存只有自己的app才能访问到 // builder.setDiskCache( new InternalCacheDiskCacheFactory( context , diskCacheSize )) ; // builder.setDiskCache( new InternalCacheDiskCacheFactory( context , diskCachePath , diskCacheSize )) ; //自定义磁盘缓存:这种缓存存在SD卡上,所有的应用都可以访问到 builder.setDiskCache( new DiskLruCacheFactory( diskCachePath , diskCacheSize )); } @Override public void registerComponents(Context context, Glide glide) { } } |
八、缓存管理
7.1、默认缓存目录和缓存大小
在Glide源码中有一个DiskCache接口,里面的Factory类定义了默认的磁盘缓存大小为:250 M , 缓存路径在:p_w_picpath_manager_disk_cache 目录下
在模拟器上可以查看缓存目录的位置,有些真机看不到这个目录,有可能数据库没有刷新的原因:
7.2、缓存模式
源码中有枚举类 DiskCacheStrategy 定义了四种缓存类型
DiskCacheStrategy.SOURCE 缓存原图
DiskCacheStrategy.RESULT 缓存和p_w_picpathview大小匹配的图
DiskCacheStrategy.ALL 既缓存原图,有缓存和p_w_picpathview大小匹配的图
DiskCacheStrategy.NONE 不做任何缓存
通过查看源码我们发现,Glide默认缓存策略是: DiskCacheStrategy.RESULT
7.3 四种缓存模式对比
比如:网络图片我们叫做 big1.jpg 宽高:3000 x 2000 大小:2.15 M 。
1 | http: //o7rvuansr.bkt.clouddn.com/big1.jpg |
客户端的 p_w_picpathview 大小:300 x 300
1 2 3 4 |
android:id= "@+id/p_w_picpath" android:layout_width= "300dp" android:layout_height= "300dp" /> |
(1) DiskCacheStrategy.SOURCE : 只会缓存一张图片,大小:2M
Glide.with( Activity2.this).load( url ).diskCacheStrategy( DiskCacheStrategy.SOURCE ).into( p_w_picpathView ) ;
(2) DiskCacheStrategy.RESULT : 只缓存了一张图片,大小:14 KB
Glide.with( Activity2.this).load( url ).diskCacheStrategy( DiskCacheStrategy.RESULT ).into( p_w_picpathView ) ;
(3) DiskCacheStrategy.ALL : 缓存了两张图片, 一张大小:2 M , 一张大小:14 KB
Glide.with( Activity2.this).load( url ).diskCacheStrategy(DiskCacheStrategy.ALL ).into( p_w_picpathView ) ;
(4) DiskCacheStrategy.NONE : 没有缓存图片
Glide.with( Activity2.this).load( url ).diskCacheStrategy(DiskCacheStrategy.NONE ).into( p_w_picpathView ) ;
7.4、 缓存场景测试
两个p_w_picpathView ,一个 100 x 100 , 一个 300 x300 ; 先加载第一张,再加载第二张
测试一 : 两张图片都在 DiskCacheStrategy.SOURCE 的情况下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | //加载第一张图 findViewById( R.id.bt1 ).setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { Glide.with( Activity2. this ).load( url ).diskCacheStrategy( DiskCacheStrategy.SOURCE ).into( p_w_picpathView1 ) ; } }); //加载第二张图 findViewById( R.id.bt2 ).setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { Glide.with( Activity2. this ).load( url ).diskCacheStrategy( DiskCacheStrategy.SOURCE ).into( p_w_picpathView2 ) ; } }); |
通过测试发现,在加载第一张图片的时候,缓存了2M 的原始图,在加载第二张的时候,就不会再请求网络,直接从缓存中加载。
测试二:第一张图在 DiskCacheStrategy.SOURCE ,第二张在DiskCacheStrategy.RESULT 情况下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | //加载第一张图 findViewById( R.id.bt1 ).setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { Glide.with( Activity2. this ).load( url ).diskCacheStrategy( DiskCacheStrategy.SOURCE ).into( p_w_picpathView1 ) ; } }); //加载第二张图 findViewById( R.id.bt2 ).setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { Glide.with( Activity2. this ).load( url ).diskCacheStrategy( DiskCacheStrategy.RESULT ).into( p_w_picpathView2 ) ; } }); |
通过测试发现,加载第一张图片的情况下,缓存了2M 的原始图。在加载第二张图片的时候,又请求网络,下载了 14 KB 的缓存。这说明,即使本地存在缓存,缓存策略不一样,缓存就不会被重用。
测试三:两张图都在 DiskCacheStrategy.RESULT 情况下 ,第一个Imageview大小: 100 x100 , 第二个p_w_picpathview大小:300 x 300
(1)先加载 100 x 100 , 加载出来后,缓存了 2 kB 的图片 ,然后加载 300 x 300 ,又重新请求网络,缓存了 14 KB 的图片 。缓存没有复用。
(2)先加载 300 x 300 , 加载出来后,缓存了 14 KB的图片。然后加载 100 x 100 ,又重新请求网络,缓存了 2 KB 的图片,缓存没有复用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | //加载第一张图 findViewById( R.id.bt1 ).setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { Glide.with( Activity2. this ).load( url ).diskCacheStrategy( DiskCacheStrategy.RESULT ).into( p_w_picpathView1 ) ; } }); //加载第二张图 findViewById( R.id.bt2 ).setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { Glide.with( Activity2. this ).load( url ).diskCacheStrategy( DiskCacheStrategy.RESULT ).into( p_w_picpathView2 ) ; } }); |
测试四:p_w_picpathView1 宽高:100 x 100 ; p_w_picpathView2 宽高:300 x 300 ; p_w_picpathView3 宽高:600 x 600
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | //加载第二张图 findViewById( R.id.bt1 ).setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { Glide.with( Activity2. this ).load( url ).into( p_w_picpathView1 ) ; } }); //加载第二张图 findViewById( R.id.bt2 ).setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { Glid
|