当前位置: 首页 > 工具软件 > glide-docs-cn > 使用案例 >

android框架 - Glide - 强大的图片加载库

郭凯
2023-12-01

Glide 4 - 强大的图片加载库

**简介:**一个强大的图片加载库,可加载本地图片、网络图片、Gif、视频。
Glide官网docs:https://muyangmin.github.io/glide-docs-cn/
可配合变换效果库:glide-transformations:https://github.com/wasabeef/glide-transformations

**优点:**Glide 支持拉取,解码和展示视频快照,图片,和GIF动画。Glide的Api是如此的灵活,开发者甚至可以插入和替换成自己喜爱的任何网络栈。默认情况下,Glide使用的是一个定制化的基于HttpUrlConnection的栈,但同时也提供了与Google Volley和Square OkHttp快速集成的工具库。

使用:

1、添加依赖库

repositories {
        jcenter()
        mavenCentral()
    }
 implementation 'com.github.bumptech.glide:glide:4.9.0'
 annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'
 implementation 'jp.wasabeef:glide-transformations:4.1.0'
权限
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

2、一般使用方法

String url = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1566894390240&di=7ed8a09c48bb298d7872a60e80367179&imgtype=0&src=http%3A%2F%2Fimg2.zol.com.cn%2Fproduct%2F103_940x705%2F258%2FceXyT7KxZC9U.jpg";
String gifUrl = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1566894290904&di=3283907b4d74878f5d290d25d6b061f0&imgtype=0&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201610%2F10%2F20161010141924_V8vUT.thumb.700_0.gif";

ImageeView imageView = findViewById(R.id.image_view);
LinearLayout linearLayout = findViewById(R.id.linear_layout);
Glide.with() 中传入Activity 或 Fragment ,此处this是使用Glide时所在的Activity

1、普通加载图片-with-load-into

Glide.with(this)
		.load(url)
		.into(imageView);

2、带占位图加载-placeholder()-error()

R.drawable.ic_photo_library和R.drawable.ic_error_outline_black_48dp为自己添加的占位图
RequestOptions requestOptions = new RequestOptions()
                .placeholder(R.drawable.ic_photo_library)
                .error(R.drawable.ic_error_outline_black_48dp);
Glide.with(this)
		.load(url)
		 .apply(requestOptions)
		 .into(imageView);

3、指定图片大小加载-override(w,h)

可封装GlideUtil类方便使用
public class GlideUtil {
    public static void load(Context context,
                     String url,
                     ImageView imageView,
                     RequestOptions requestOptions){
        Glide.with(context)
                .load(url)
                .apply(requestOptions)
                .into(imageView);
    }
}

使用:

//override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINA)加载原图(非压缩)
//注意:此处的Target是com.bumptech.glide.request.target包下的
 RequestOptions options = new RequestOptions()
                .override(200, 100);//(宽, 高)
 GlideUtil.load(this, url, imageView, options);

4、缓存机制-CacheStrategy

默认情况下,Glide 会在开始一个新的图片请求之前检查以下多级的缓存:

  1. 活动资源 (Active Resources) - 现在是否有另一个 View 正在展示这张图片?
  2. 内存缓存 (Memory cache) - 该图片是否最近被加载过并仍存在于内存中?
  3. 资源类型(Resource) - 该图片是否之前曾被解码、转换并写入过磁盘缓存?
  4. 数据来源 (Data) - 构建这个图片的资源是否之前曾被写入过文件缓存?
    前两步检查图片是否在内存中,如果是则直接返回图片。后两步则检查图片是否在磁盘上,以便快速但异步地返回图片。
    如果四个步骤都未能找到图片,则Glide会返回到原始资源以取回数据(原始文件,Uri, Url等)。

常用:
1、new RequestOptions().diskCacheStrategy(DiskCacheStrategy.NONE);
调用diskCacheStrategy()方法并传入DiskCacheStrategy.NONE,就可以禁用掉Glide的硬盘缓存功能了。
这个diskCacheStrategy()方法基本上就是Glide硬盘缓存功能的一切,它可以接收五种参数:
* DiskCacheStrategy.NONE: 表示不缓存任何内容。
* DiskCacheStrategy.DATA: 表示只缓存原始图片。
* DiskCacheStrategy.RESOURCE: 表示只缓存转换过后的图片。
* DiskCacheStrategy.ALL : 表示既缓存原始图片,也缓存转换过后的图片。
* DiskCacheStrategy.AUTOMATIC: 表示让Glide根据图片资源智能地选择使用哪一种缓存策略(默认选项)。
2、Glide自动就是开启内存缓存的,skipMemoryCache为ture即禁用改功能

        RequestOptions options = new RequestOptions()
                .skipMemoryCache(true)
                .diskCacheStrategy(DiskCacheStrategy.NONE);
        GlideUtil.load(this, url, imageView, options);

5、指定加载格式-into()自动识别

在Glide 3中的语法是先load()再asXXX()的。
而在Glide 4中是先asXXX()再load()的,一般直接跟在with()后面。
.asBitmap()方法,只允许加载静态图片,如果是gif则加载第一帧
.asGif(),强制指定加载动态图片。
.asFile(),强制指定文件格式的加载。
.asDrawable(),强制Drawable格式的加载。

		//R.drawable.ic_photo_library为自己添加的占位图
		RequestOptions options = new RequestOptions()
                .placeholder(R.drawable.ic_photo_library);
        Glide.with(this)
                .load(gifUrl)
                .apply(options)
                .into(imageView);

6-1、回调与监听-into()传Target

例如:into()不能直接传入LinearLayout之类的布局对象,所以要创建Taget

SimpleTarget<Drawable> target = new SimpleTarget<Drawable>() {
            @Override
            public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
                //resourse是Glide加载出来的图片对象
                linearLayout.setBackground(resource);
            }
        };
Glide.with(this)
         .load(url)
         .into(target);

6-2、回调与监听-preload()预加载

提前对图片进行一个预加载,等真正需要加载图片的时候就直接从缓存中读取

 Glide.with(this)
                .load(url)
                .preload();
Glide.with(this).load(url).into(imageView);

6-3、回调与监听-submit()下载图片

其中submit()方法是用于下载原始尺寸的图片,而submit(int width, int height)则可以指定下载图片的尺寸。调用后立即返回FutureTarget对象,之后后台下载图片,待下载完,调用FutureTarget的get()方法就可以去获取下载好的图片文件,若图片未下载完get()方法就会阻塞线程,所以新开线程下载。
建议使用线程池,可参考:https://blog.csdn.net/weixin_44565784/article/details/100101695
步骤:
1、提前写了一个拷贝文件的工具类(FileUtil.java)
为节省篇幅,工具类代码参见文章步骤3:https://blog.csdn.net/weixin_44565784/article/details/100101695
2、下载图片

new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    File file = Glide.with(getApplicationContext())
                    							.asFile()
                    							.load(url)
                    							.submit()
                    							.get();
                    File DCIMdir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getAbsoluteFile();
                    if (!DCIMdir.exists()) {
                        DCIMdir.mkdir();
                    }
                    String fileName = System.currentTimeMillis() + ".jpg";
                    File targetFile = new File(DCIMdir, fileName);
                    //将下载的图片文件复制到本地图片文件
                    FileUtil.copyFile(file, targetFile);
                    Snackbar.make(view, "图片已保存。\n" + targetFile.getPath(), Snackbar.LENGTH_SHORT).show();
                    //通知图库更新
                    sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
                            Uri.fromFile(new File(targetFile.getParent()))));
                } catch (ExecutionException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();

6-4、回调与监听-asBitmap()下载图片

方法和6-3差不多,可能是版本不同导致不能.toByte[],所以用Target接受Bitmap,再转byte[]

SimpleTarget<Bitmap> target = new SimpleTarget<Bitmap>() {
            @Override
            public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {

                File DCIMdir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getAbsoluteFile();
                if (!DCIMdir.exists()) {
                    DCIMdir.mkdir();
                }
                String fileName = System.currentTimeMillis() + ".jpg";
                File targetFile = new File(DCIMdir, fileName);
				//bitmap 转 byte[] 
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                resource.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
                byte[] bytes = outputStream.toByteArray();
                
                FileUtil.copyByBytes(bytes, targetFile);
                Snackbar.make(view, "图片已保存。\n" + targetFile.getPath(), Snackbar.LENGTH_SHORT).show();
                //通知图库更新
                sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
                        Uri.fromFile(new File(targetFile.getParent()))));
            }
        };
        Glide.with(this)
                .asBitmap()
                .load(url)
                .into(target);
    }

6-5、回调与监听-listener()监听状态

onResourceReady()方法中返回了true,那么就不会再回调Target的onResourceReady()方法了

Glide.with(this)
                .load(url)
                .listener(new RequestListener<Drawable>() {
                    @Override
                    public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                        return false;
                    }

                    @Override
                    public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                        return false;
                    }
                })
                .into(imageView);

7-1、图片变换-transform

transform(…)方法,将想要执行的图片变换操作作为参数传入transforms()方法即可,其现成封装了centerCrop、fitCenter、circleCrop

RequestOptions requestOptions = new RequestOptions()
                .circleCrop();
GlideUtil.load(this, url, imageView, requestOptions);

7-2、图片变换-glide-transformations

引入glide-transformations,它实现了很多通用的图片变换效果,如裁剪变换、颜色变换、模糊变换等等

RequestOptions transform = new RequestOptions()
                .fitCenter()
                .transform(new BlurTransformation());
Glide.with(this)
                .load(url)
                .apply(transform)
                .into(imageView);

8、自定义模块-AppGlideModule

继承AppGlideModule,对Glide的各种配置进行重写,实现自定义
1、新建一个类(MyGlideModule.java),继承 AppGlideModule,开头添加@GlideModule注释,记得添加依赖…:compiler:…,Rebuild Project就能使用GlideApp了

@GlideModule
public class MyGlideModule extends AppGlideModule {
    @Override
    public void applyOptions(@NonNull Context context, @NonNull GlideBuilder builder) {
        builder.setDiskCache(new ExternalPreferredCacheDiskCacheFactory(context));
    }
}

2、使用GlideApp

GlideApp.with(this)
                .load(url)
                .into(imageView);

更多介绍:https://www.jianshu.com/p/84932a0eb68b

注意:在Glide4中不需要注册就能识别@GlideModule
//在Glide4中不需要
  <meta-data
            android:name="完整包名"
            android:value="GlideModule" />

9-1、使用Generated API

使用Generated API (使用前要有自定义类和加上@GlideModule注解(里面可以不写方法),才能使用GlideApp)。Generated API是Glide 4中全新引入的一个功能,它的工作原理是使用注解处理器 (Annotation Processor) 来生成出一个API,在Application模块中可使用该流式API一次性调用到RequestBuilder,RequestOptions和集成库中所有的选项。

//diskCacheStrategy、placeholder在RequestOptions中
        GlideApp.with(this)
                .load(url)
                .circleCrop()
                .diskCacheStrategy(DiskCacheStrategy.NONE)
                .placeholder(R.drawable.ic_photo_library)
                .into(imageView);

9-2、使用Generated API-自定义

借助 @GlideExtension和 @GlideOption这两个注解可自己的API
1、自定义API类,记得添加注解

@GlideExtension
public class MyAPI {
    /**
     * 构造函数声明成private
     */
    private MyAPI(){}

    /**
     *方法都必须是静态方法,
     * 而且第一个参数必须是RequestOptions,后面你可以加入任意多个你想自定义的参数
     * @param requestOptions
     */
    @GlideOption
    public static BaseRequestOptions<?> cacheSource(BaseRequestOptions<?> requestOptions){
        return requestOptions.override(400, 400);
    }
}

2、使用

//cacheSource()为自定义的API
GlideApp.with(this)
                .load(url)
                .cacheSource()
                .into(imageView);

----------------完---------------

 类似资料: