图片加载之Glide使用总结

概述

作为Glide是谷歌推荐的图片加载库,Glide又着 支持video,Gif,SVG格式,同时有着很好的生命周期管理,支持Volley,OkHttp,更好的内存管理策略等优点。

相关方法

  • with():指定了声明周期
  • load():加载资源,String/Uri/File/Integer/URL/byte[]/T,或者 loadFromMediaStore(Uri uri)
  • placeholder(resourceId/drawable): 设置资源加载过程中的占位Drawable。
  • error():load失败时显示的Drawable。
  • crossFade()/crossFade(int duration):imageView改变时的动画,version 3.6.1后默认开启300毫秒
  • dontAnimate():移除所有的动画。
  • override() :调整图片大小
  • centerCrop():图片裁剪,ImageView 可能会完全填充,但图像可能不会完整显示。
  • fitCenter(): 图像裁剪,图像将会完全显示,但可能不会填满整个 ImageView。
  • animate(): 指定加载动画。
  • transform():图片转换。
  • bitmapTransform(): bitmap转换,不可以和(centerCrop() 或 fitCenter())共用。
  • priority(Priority priority):当前线程的优先级,Priority.IMMEDIATE,Priority.HIGH,Priority.NORMAL(default),Priority.LOW
  • thumbnail(): 缩略图.
  • listener():异常监听
  • preload(int width, int height): 预加载resource到缓存中(单位为pixel)
  • fallback(Drawable drawable):设置model为空时显示的Drawable。
  • using() :为单个的请求指定一个 model
  • asGif():Gif 检查,如果是图片且加了判断,则会显示error占位图,否则会显示图片
  • asBitmap():bitmap转化,如果是gif,则会显示第一帧

Glide 可以以load(File)的形式播放本地视频,但是如果需要播放网络视屏,则要用VideoView

缓存策略

一张图片变化很快,需要禁止内存缓存

.skipMemoryCache(true)
 
 
    • 1

    即使关闭内存缓存,请求图片将会仍然被存储在设备的磁盘缓存中,如果一张图片变化很快,仍需要禁止磁盘缓存

    .diskCacheStrategy(DiskCacheStrategy.NONE)
     
     
      • 1

      Glide 缓存了原始图像,全分辨率图像和另外小版本的图像,因此禁用磁盘缓存是用枚举来控制的

      DiskCacheStrategy.NONE //什么都不缓存,就像刚讨论的那样
      DiskCacheStrategy.SOURCE //仅仅只缓存原来的全分辨率的图像。在我们上面的例子中,将会只有一个 1000x1000 像素的图片
      DiskCacheStrategy.RESULT //仅仅缓存最终的图像,即,降低分辨率后的(或者是转换后的)
      DiskCacheStrategy.ALL //缓存所有版本的图像(默认行为)
       
       
        • 1
        • 2
        • 3
        • 4

        Glide使用InternalCacheDiskCacheFactory类建立磁盘缓存。目录在 
        /data/data/<package-name>/cache,其他应用程序无法访问。

        自定义缓存策略:

        磁盘缓存,用类DiskLruCacheWrapper来设置目录

        builder.setDiskCache(new DiskCache.Factory() {
                    @Override
                    public DiskCache build() {
                    // 自己的缓存目录
                        File imgFile = new File(Environment.getExternalStorageDirectory()+"/Android/data/package-name");
                        return DiskLruCacheWrapper.get(imgFile,DiskCache.Factory.DEFAULT_DISK_CACHE_SIZE);
                    }
                });
         
         
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8

          内存缓存,用类Memory Cache 来设置大小

          MemorySizeCalculator calculator = new MemorySizeCalculator(context); 
          builder.setMemoryCache(new LruResourceCache(calculator.getMemoryCacheSize()));
           
           
            • 1
            • 2

            Bitmap Pool

            重复使用及销毁策略。设置方法:GlideBuilder.setBitmapPool() 
            默认采用的是LruBitmapPool,使用了LRU算法。

            MemorySizeCalculator calculator = new MemorySizeCalculator(context);
            int defaultBitmapPoolSize = calculator.getBitmapPoolSize();
            int customBitmapPoolSize = (int) (1.2 * defaultBitmapPoolSize);
            builder.setBitmapPool( new LruBitmapPool( customBitmapPoolSize );
             
             
              • 1
              • 2
              • 3
              • 4

              Bitmap Format

              Bitmap Format用于设置全局缺省首选Bitmap规格,设置方法:GlideBuilder.setDecodeFormat() 
              默认采用RGB_565(比ARGB_8888节省一半的内存),但不支持透明度。

              优先级

              会发现优先级高的先 显示出来,即是图片比较大。

                  //优先加载
                  Glide
                      .with(context)
                      .load(heroImageUrl)
                      .priority(Priority.HIGH)
                      .into(imageViewHero);
                  //后加载
                  Glide
                      .with(context)
                      .load(itemImageUrl)
                      .priority(Priority.LOW)
                      .into(imageViewItem);
               
               
                • 1
                • 2
                • 3
                • 4
                • 5
                • 6
                • 7
                • 8
                • 9
                • 10
                • 11
                • 12

                先显示缩略图,后显示原图

                   //用原图的1/10作为缩略图
                    Glide
                        .with(this)
                        .load("http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png")
                        .thumbnail(0.1f)
                        .into(iv_0);
                    //用其它图片作为缩略图
                    DrawableRequestBuilder<Integer> thumbnailRequest = Glide
                        .with(this)
                        .load(R.drawable.news);
                    Glide.with(this)
                        .load("http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png")
                        .thumbnail(thumbnailRequest)
                        .into(iv_0);
                 
                 
                  • 1
                  • 2
                  • 3
                  • 4
                  • 5
                  • 6
                  • 7
                  • 8
                  • 9
                  • 10
                  • 11
                  • 12
                  • 13
                  • 14

                  图片处理

                  裁剪、模糊、滤镜等。可以s使用 wasabeef/glide-transformations ,

                  实现Transformation 接口,或者使用抽象类BitmapTransformation, 
                  通过transform()或bitmapTransform()来处理图片

                      //圆形裁剪
                      Glide.with(this)
                          .load("http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png")
                          .bitmapTransform(new CropCircleTransformation(this))
                          .into(iv_0);
                      //圆角处理
                      Glide.with(this)
                          .load("http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png")
                          .bitmapTransform(new RoundedCornersTransformation(this,30,0, RoundedCornersTransformation.CornerType.ALL))
                          .into(iv_0);
                      //灰度处理
                      Glide.with(this)
                          .load("http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png")
                          .bitmapTransform(new GrayscaleTransformation(this))
                          .into(iv_0);
                      //模糊处理
                      Glide.with(this).load(R.drawable.demo)
                              .bitmapTransform(new BlurTransformation(context))
                              .into((ImageView) findViewById(R.id.image));
                      //其它变换...
                   
                   
                    • 1
                    • 2
                    • 3
                    • 4
                    • 5
                    • 6
                    • 7
                    • 8
                    • 9
                    • 10
                    • 11
                    • 12
                    • 13
                    • 14
                    • 15
                    • 16
                    • 17
                    • 18
                    • 19
                    • 20

                    自定义转换

                    public class BlurTransformation extends BitmapTransformation {
                    
                        public BlurTransformation(Context context) {
                            super( context );
                        }
                    
                        @Override
                        protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
                            return null; // todo
                        }
                    
                        @Override
                        public String getId() {
                            return null; // todo
                        }
                    }
                     
                     
                      • 1
                      • 2
                      • 3
                      • 4
                      • 5
                      • 6
                      • 7
                      • 8
                      • 9
                      • 10
                      • 11
                      • 12
                      • 13
                      • 14
                      • 15
                      • 16

                      其中getId() :描述了这个转换的唯一标识符,将作为缓存系统的一部分

                      可以使用单种转换和多种转换,如多种转换:

                      Glide  
                          .with( context )
                          .load( eatFoodyImages[1] )
                          .transform( new GreyscaleTransformation( context ), new BlurTransformation( context ) )
                          .into( imageView2 );
                       
                       
                        • 1
                        • 2
                        • 3
                        • 4
                        • 5

                        回调 Target

                        SimpleTarget

                        target 泛型:Bitmap,GlideDrawable,GifDrawable 
                        其中使用字段声明target’而不是使用匿名内部类的形式,可以避免被垃圾回收机制回收,而回调为空的现象。

                        private SimpleTarget target = new SimpleTarget<Bitmap>() {  
                            @Override
                            public void onResourceReady(Bitmap bitmap, GlideAnimation glideAnimation) {
                                // do something with the bitmap
                                // for demonstration purposes, let's just set it to an ImageView
                                imageView1.setImageBitmap( bitmap );
                            }
                        };
                        
                        private void loadImageSimpleTarget() {  
                            Glide
                                .with( context ) // could be an issue!
                                .load( eatFoodyImages[0] )
                                .asBitmap()
                                .into( target );
                        }
                         
                         
                          • 1
                          • 2
                          • 3
                          • 4
                          • 5
                          • 6
                          • 7
                          • 8
                          • 9
                          • 10
                          • 11
                          • 12
                          • 13
                          • 14
                          • 15
                          • 16

                          Target生命周期

                          with( context ):关系到生命周期。如果请求需要在 activity 生命周期之外去做时,需要使用:

                          private void loadImageSimpleTargetApplicationContext() {  
                              Glide
                                  .with( context.getApplicationContext() ) // safer!
                                  .load( eatFoodyImages[1] 
                                  .asBitmap()
                                  .into( target2 );
                          }
                           
                           
                            • 1
                            • 2
                            • 3
                            • 4
                            • 5
                            • 6
                            • 7

                            Target 指定尺寸

                            使用ImageView 作为参数给 .into()的时候,Glide 会用 ImageView 的大小去限制图像的大小 
                            但是target并没有已知的大小,如果知道图片大小则应指出,减少内存消耗。

                            private SimpleTarget target2 = new SimpleTarget<Bitmap>( 250, 250 ) {  
                                @Override
                                public void onResourceReady(Bitmap bitmap, GlideAnimation glideAnimation) {
                                    imageView2.setImageBitmap( bitmap );
                                }
                            };
                            
                            private void loadImageSimpleTargetApplicationContext() {  
                                Glide
                                    .with( context.getApplicationContext() ) // safer!
                                    .load( eatFoodyImages[1] )
                                    .asBitmap()
                                    .into( target2 );
                            }
                             
                             
                              • 1
                              • 2
                              • 3
                              • 4
                              • 5
                              • 6
                              • 7
                              • 8
                              • 9
                              • 10
                              • 11
                              • 12
                              • 13
                              • 14

                              ViewTarget

                              常用于自定以控件中,比如自定义控件中组合了ImageView控件,如下

                              public class FutureStudioView extends FrameLayout {  
                                  ImageView iv;
                                  TextView tv;
                              
                                  public void initialize(Context context) {
                                      inflate( context, R.layout.custom_view_futurestudio, this );
                              
                                      iv = (ImageView) findViewById( R.id.custom_view_image );
                                      tv = (TextView) findViewById( R.id.custom_view_text );
                                  }
                              
                                  public FutureStudioView(Context context, AttributeSet attrs) {
                                      super( context, attrs );
                                      initialize( context );
                                  }
                              
                                  public FutureStudioView(Context context, AttributeSet attrs, int defStyleAttr) {
                                      super( context, attrs, defStyleAttr );
                                      initialize( context );
                                  }
                              
                                  public void setImage(Drawable drawable) {
                                      iv = (ImageView) findViewById( R.id.custom_view_image );
                              
                                      iv.setImageDrawable( drawable );
                                  }
                              }
                               
                               
                                • 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

                                使用如下方法给自定义控件中的ImageView设置图片

                                private void loadImageViewTarget() {  
                                    FutureStudioView customView = (FutureStudioView) findViewById( R.id.custom_view );
                                
                                    //传递了参数 customView
                                    viewTarget = new ViewTarget<FutureStudioView, GlideDrawable>( customView ) {
                                        @Override
                                        public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> glideAnimation) {
                                        //调用了FutureStudioView的setImage方法
                                            this.view.setImage( resource.getCurrent() );
                                        }
                                    };
                                
                                    Glide
                                        .with( context.getApplicationContext() ) // safer!
                                        .load( eatFoodyImages[2] )
                                        .into( viewTarget );
                                }
                                 
                                 
                                  • 1
                                  • 2
                                  • 3
                                  • 4
                                  • 5
                                  • 6
                                  • 7
                                  • 8
                                  • 9
                                  • 10
                                  • 11
                                  • 12
                                  • 13
                                  • 14
                                  • 15
                                  • 16
                                  • 17

                                  NotificationTarget

                                  用于加载图片到通知栏和应用小部件中的,具体见 http://mrfu.me/

                                  动画

                                  animate() :可以加载资源文件animate.xml文件 
                                  或者 属性动画:

                                  • ViewPropertyAnimation
                                  • ViewAnimation
                                  • NoAnimation
                                  • DrawableCrossFadeViewAnimation
                                  ViewPropertyAnimation.Animator animationObject = new ViewPropertyAnimation.Animator() {  
                                      @Override
                                      public void animate(View view) {
                                          // if it's a custom view class, cast it here
                                          // then find subviews and do the animations
                                          // here, we just use the entire view for the fade animation
                                          view.setAlpha( 0f );
                                  
                                          ObjectAnimator fadeAnim = ObjectAnimator.ofFloat( view, "alpha", 0f, 1f );
                                          fadeAnim.setDuration( 2500 );
                                          fadeAnim.start();
                                      }
                                  };
                                  
                                  Glide  
                                      .with( context )
                                      .load( eatFoodyImages[1] )
                                      .animate( animationObject )
                                      .into( imageView2 );
                                   
                                   
                                    • 1
                                    • 2
                                    • 3
                                    • 4
                                    • 5
                                    • 6
                                    • 7
                                    • 8
                                    • 9
                                    • 10
                                    • 11
                                    • 12
                                    • 13
                                    • 14
                                    • 15
                                    • 16
                                    • 17
                                    • 18
                                    • 19

                                    Glide module

                                    Glide module 是一个抽象方法,全局改变 Glide 行为的一个方式。 
                                    前面单策略的定义中都用到了GlideBuilder类 
                                    如果你需要访问 GlideBuilder,你需要去实现一个 GlideModule 接口的公共类

                                    public class FileGlideModule  implements GlideModule{
                                        @Override
                                        public void applyOptions(final Context context, GlideBuilder builder) {
                                    //builder 内的所有方法你都可以设置。
                                    //        builder.setDiskCache(new InternalCacheDiskCacheFactory(context));
                                            builder.setDiskCache(new ExternalCacheDiskCacheFactory(context));
                                          /*  builder.setDiskCache(new DiskCache.Factory() {
                                                @Override
                                                public DiskCache build() {
                                                    File imgFile = new File(Environment.getExternalStorageDirectory()+"/Android/data/com.leying365");
                                                    return DiskLruCacheWrapper.get(imgFile,DiskCache.Factory.DEFAULT_DISK_CACHE_SIZE);
                                                }
                                            });*/
                                            MemorySizeCalculator calculator = new MemorySizeCalculator(context);
                                            builder.setMemoryCache(new LruResourceCache(calculator.getMemoryCacheSize()));
                                            builder.setBitmapPool(new LruBitmapPool(calculator.getBitmapPoolSize()));
                                            builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
                                        }
                                    
                                        @Override
                                        public void registerComponents(Context context, Glide glide) {
                                    
                                        }
                                    }
                                     
                                     
                                      • 1
                                      • 2
                                      • 3
                                      • 4
                                      • 5
                                      • 6
                                      • 7
                                      • 8
                                      • 9
                                      • 10
                                      • 11
                                      • 12
                                      • 13
                                      • 14
                                      • 15
                                      • 16
                                      • 17
                                      • 18
                                      • 19
                                      • 20
                                      • 21
                                      • 22
                                      • 23
                                      • 24

                                      最终通过<meta-data android:name=”com.mypackage.MyGlideModule” tools:node=”GlideModule” /> 来生效

                                      常用方法:

                                      • setMemoryCache(MemoryCache memoryCache)
                                      • setBitmapPool(BitmapPool bitmapPool)
                                      • setDiskCache(DiskCache.Factory diskCacheFactory)
                                      • setDiskCacheService(ExecutorService service)
                                      • setResizeService(ExecutorService service)
                                      • setDecodeFormat(DecodeFormat decodeFormat)

                                      网络库

                                      Glide 使用ModeLoader 接口来 集成网络库,Glide提供了两种网络库 的实现,分别为OkHttp 和 Volley。

                                      在build.gradle中添加如下依赖,glide会默认使用OKhttp来做所有的网络连接

                                      dependencies {  
                                          // your other dependencies
                                          // ...
                                      
                                          // Glide
                                          compile 'com.github.bumptech.glide:glide:3.6.1'
                                      
                                          // Glide's OkHttp Integration 
                                          compile 'com.github.bumptech.glide:okhttp-integration:1.3.1@aar'
                                          compile 'com.squareup.okhttp:okhttp:2.5.0'
                                      }
                                      
                                       
                                       
                                        • 1
                                        • 2
                                        • 3
                                        • 4
                                        • 5
                                        • 6
                                        • 7
                                        • 8
                                        • 9
                                        • 10
                                        • 11
                                        • 12

                                        上面会将必要的GlideModule 到你的 Android.Manifest中。

                                        缓存与失效机制

                                        Glide 通过 url、viewwidth、viewheight、屏幕的分辨率等以一种散列算法生成一个独有、安全的文件名作为key保存到disk上.因为其是通过一个散列算法来实现的,因此很难定位文件的缓存,幸好Glide提供了signature()方法允许将一个附加的数据加入到缓存key当中,可以用来保证缓存的及时性.

                                        系统默认实现了MediaStoreSignature,StringSignature.

                                        Glide.with(fragment)
                                            .load(mediaStoreUri)
                                            .signature(new MediaStoreSignature(mimeType, dateModified, orientation))
                                            .into(view);
                                         
                                         
                                          • 1
                                          • 2
                                          • 3
                                          • 4

                                          当然也可以自己来实现Signature

                                          public class MSignature implements Key {
                                          
                                              @Override
                                              public boolean equals(Object o) {
                                               //...
                                              }
                                              @Override
                                              public int hashCode() {
                                                 //...
                                              }
                                              @Override
                                              public void updateDiskCacheKey(MessageDigest messageDigest) {
                                                  messageDigest.update(ByteBuffer.allocate(Integer.SIZE)
                                          .putInt(signature).array());
                                              }
                                          }
                                           
                                           
                                            • 1
                                            • 2
                                            • 3
                                            • 4
                                            • 5
                                            • 6
                                            • 7
                                            • 8
                                            • 9
                                            • 10
                                            • 11
                                            • 12
                                            • 13
                                            • 14
                                            • 15
                                            • 16

                                            极端情况,不缓存可以用diskCacheStrategy(DiskCacheStrategy.NONE.)来实现

                                            图片下载

                                            Glide除了提供into方法来加载图片外,也提供了downloadOnly方法来实现图片下载.

                                            FutureTarget<File> future = Glide.with(applicationContext)
                                                .load(yourUrl)
                                                .downloadOnly(500, 500);
                                            File cacheFile = future.get();
                                             
                                             
                                              • 1
                                              • 2
                                              • 3
                                              • 4

                                              下载之后可以通过如下方式来加载图片

                                              Glide.with(yourFragment)
                                                  .load(yourUrl)
                                                  //DiskCacheStrategy.ALL或者DiskCacheStrategy.SOURCE可以保证程序会先去读缓存文件
                                                  .diskCacheStrategy(DiskCacheStrategy.ALL)
                                                  .into(yourView);
                                               
                                               
                                                • 1
                                                • 2
                                                • 3
                                                • 4
                                                • 5

                                                如果想获取一张图片的Bitmap,可以使用如下方式

                                                //此方法需要try/catch处理,并且最好在子线程中,否则会阻塞主线程
                                                Bitmap myBitmap = Glide.with(applicationContext)
                                                    .load(yourUrl)
                                                    .asBitmap()
                                                    .centerCrop()
                                                    //设置大小
                                                    .into(500, 500)
                                                    .get()
                                                 
                                                 
                                                  • 1
                                                  • 2
                                                  • 3
                                                  • 4
                                                  • 5
                                                  • 6
                                                  • 7
                                                  • 8

                                                  参考:http://mrfu.me/

                                                  使用demo:GlidePlayActivity.java

                                                  • 0
                                                    点赞
                                                  • 0
                                                    收藏
                                                    觉得还不错? 一键收藏
                                                  • 0
                                                    评论
                                                  评论
                                                  添加红包

                                                  请填写红包祝福语或标题

                                                  红包个数最小为10个

                                                  红包金额最低5元

                                                  当前余额3.43前往充值 >
                                                  需支付:10.00
                                                  成就一亿技术人!
                                                  领取后你会自动成为博主和红包主的粉丝 规则
                                                  hope_wisdom
                                                  发出的红包
                                                  实付
                                                  使用余额支付
                                                  点击重新获取
                                                  扫码支付
                                                  钱包余额 0

                                                  抵扣说明:

                                                  1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
                                                  2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

                                                  余额充值