每天学习一个Android中的常用框架——10.Glide

野性酷女 2023-03-13 06:00 92阅读 0赞

文章目录

    1. 简介
    1. 特性
    1. 演示
    • 3.1 集成
    • 3.2 配置
    • 3.2 基本功能
    • 3.3 拓展功能
      • 3.3.1 四种形式的图片加载
      • 3.3.2 带有占位图的图片加载
      • 3.3.3 静态图片的图片加载
      • 3.3.4 动态图片的图片加载
      • 3.3.5 指定大小图片的图片加载
      • 3.3.6 不带缓存的图片加载
    1. 源码地址

1. 简介

Glide,作为一个当下主流的专门用于图片加载的框架,以其简明的语法和高效的性能而闻名。有关Glide的官方说明,可以参考下面这段Glide的中文文本说明,取自于Glide v4 快速高效的Android图片加载库,即:

Glide是一个快速高效的Android图片加载库,注重于平滑的滚动。Glide提供了易用的API,高性能、可扩展的图片解码管道(decode pipeline),以及自动的资源池技术。
Glide 支持拉取,解码和展示视频快照,图片,和GIF动画。Glide的Api是如此的灵活,开发者甚至可以插入和替换成自己喜爱的任何网络栈。默认情况下,Glide使用的是一个定制化的基于HttpUrlConnection的栈,但同时也提供了与Google Volley和Square OkHttp快速集成的工具库。
虽然Glide的主要目标是让任何形式的图片列表的滚动尽可能地变得更快、更平滑,但实际上,Glide几乎能满足你对远程图片的拉取/缩放/显示的一切需求。

当然,由于Glide被收录到了《第一行代码 Android》中,我也很早地就接触到了这个框架。作为第一个接触到的图片加载框架,我对它的印象也比较深。趁着这次框架学习之时,我便想要再度复习这个已经因为长时不用而有些陌生的框架。

说实话,最开始在学习Android的时候,我并不知道使用图片加载的系列框架会带来什么好处,因为原生的Android就已经提供了相应的api语句。当Android的学习愈发深入后,才深刻理解到这些框架的益处。如果只用原生的api语句实现图片加载,可能会出现各种意想不到的问题。而图片加载框架的引入,解决了包括三级缓存ANR等一系列优化问题。正因如此,我们更需要学习该系列框架的使用,为以后的项目开发打好扎实的基础。

话不多活,让我们马上开始Glide的学习吧。

2. 特性

根据官方文档的说明,Glide的特性可以分由三个方面进行讲解:

  • API
    Glide 使用简明的流式语法API,这是一个非常棒的设计,因为它允许你在大部分情况下一行代码搞定需求:

    1. Glide.with(fragment)
    2. .load(url)
    3. .into(imageView);

    这句描述确实不夸张,因为Glide的大部分业务基本上都是倚靠这行代码就可以实现

  • 性能
    Glide 充分考虑了Android图片加载性能的两个关键方面:

    • 图片解码速度
    • 解码图片带来的资源压力

    为了让用户拥有良好的App使用体验,图片不仅要快速加载,而且还不能因为过多的主线程I/O或频繁的垃圾回收导致页面的闪烁和抖动现象。

  • 步骤
    Glide使用了多个步骤来确保在Android上加载图片尽可能的快速和平滑:

    • 自动、智能地下采样(downsampling)和缓存(caching),以最小化存储开销和解码次数;
    • 积极的资源重用,例如字节数组和Bitmap,以最小化昂贵的垃圾回收和堆碎片影响;
    • 深度的生命周期集成,以确保仅优先处理活跃的Fragment和Activity的请求,并有利于应用在必要时释放资源以避免在后台时被杀掉。

正因为Glide具有这三方面的优点,于是成为了当下主流的图片加载框架。说实话,它的使用确实相当简单。在接下来的演示环节中,读者就可以感受到。

3. 演示

3.1 集成

在使用框架之前,第一步永远都是集成。我们去Glide的GitHub官网上搜索最新版本:Glide,然后修改module下的build.gradle,代码如下:

  1. implementation 'com.github.bumptech.glide:glide:4.11.0'
  2. annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'

3.2 配置

在使用Glide的时候,我们可能需要申请一些权限。修改Manifest.xml,添加相应权限,代码如下:

  1. <uses-permission android:name="android.permission.INTERNET"/>
  2. <!-- Allows Glide to monitor connectivity status and restart failed requests if users go from a a disconnected to a connected network state. -->
  3. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
  4. <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  5. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

3.2 基本功能

这里为了演示Glide提供的最基本的图片加载功能,就使用尽可能简单的业务逻辑。修改activity_main.xml,增加一个ImageView控件和两个按钮,按钮分别作用与让图片的显示和图片的清除,代码如下:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <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" tools:context=".MainActivity" android:orientation="vertical">
  3. <Button android:id="@+id/btn_load_image" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="加载图片"/>
  4. <Button android:id="@+id/btn_unload_image" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="取消加载"/>
  5. <ImageView android:id="@+id/iv_standard" android:layout_width="wrap_content" android:layout_height="wrap_content" />
  6. </LinearLayout>

修改MainActivity,首先添加initUI()方法,用于初始化布局中的三个控件,然后构造一个File对象,将手机中的一张名为test.jpg的图片封装起来(注意:这里获取路径名的api为context.getExternalFilesDir(),而没有用之前的Environment.getExternalStorageState()。这是因为Android X的新特性:作用域存储,即每个应用只能自己的应用路径下存放文件,而不是像之前一样直接在sdcard上,该局api可以获取到的路径为:/storage/emulated/0/Android/data/<包名>/files),另外,实现了两个按钮的点击方法,每个按钮中的方法仅有一行代码,代码如下:

  1. import androidx.appcompat.app.AppCompatActivity;
  2. import android.os.Bundle;
  3. import android.view.View;
  4. import android.widget.Button;
  5. import android.widget.ImageView;
  6. import com.bumptech.glide.Glide;
  7. import java.io.File;
  8. public class MainActivity extends AppCompatActivity {
  9. private ImageView iv_standard;
  10. private Button btn_load_image;
  11. private Button btn_unload_image;
  12. private File mImageFile;
  13. @Override
  14. protected void onCreate(Bundle savedInstanceState) {
  15. super.onCreate(savedInstanceState);
  16. setContentView(R.layout.activity_main);
  17. // 初始化UI
  18. initUI();
  19. // 为mImageFile赋予实例对象
  20. mImageFile = new File(this.getExternalFilesDir(null) + File.separator + "test.jpg");
  21. // 1.加载图片
  22. loadImage();
  23. // 2.取消图片加载
  24. unloadImage();
  25. }
  26. /** * 初始化UI */
  27. private void initUI() {
  28. iv_standard = findViewById(R.id.iv_standard);
  29. btn_load_image = findViewById(R.id.btn_load_image);
  30. btn_unload_image = findViewById(R.id.btn_unload_image);
  31. }
  32. /** * 1.加载图片 */
  33. private void loadImage() {
  34. btn_load_image.setOnClickListener(new View.OnClickListener() {
  35. @Override
  36. public void onClick(View v) {
  37. Glide.with(getApplicationContext())
  38. .load(mImageFile)
  39. .into(iv_standard);
  40. }
  41. });
  42. }
  43. /** * 2.取消图片加载 */
  44. private void unloadImage(){
  45. btn_unload_image.setOnClickListener(new View.OnClickListener() {
  46. @Override
  47. public void onClick(View v) {
  48. Glide.with(getApplicationContext())
  49. .clear(iv_standard);
  50. }
  51. });
  52. }
  53. }

编写完成后,接下来运行程序,可以看到我们刚刚编写好的布局界面,如图所示:
在这里插入图片描述
点击“加载图片”按钮,图片就会显示到ImageView控件上,如图所示:
在这里插入图片描述
如果点击“取消加载”按钮,图片就会消失。反复来回点击这两个按钮,就可以控制图片的加载和清除。这样,就实现了Glide最基本的功能:图片加载。

当然,Glide的功能远远不止这个。在下面的小节中,将讲解Glide的一些拓展功能。当然,限于篇幅限制,接下来就只贴出业务逻辑代码和一些简单的说明,就不一一详解了。

3.3 拓展功能

3.3.1 四种形式的图片加载

  1. // 加载本地图片
  2. File file = new File(getExternalCacheDir() + "/image.jpg");
  3. Glide.with(this).load(file).into(imageView);
  4. // 加载应用资源
  5. int resource = R.drawable.image;
  6. Glide.with(this).load(resource).into(imageView);
  7. // 加载二进制流
  8. byte[] image = getImageBytes();
  9. Glide.with(this).load(image).into(imageView);
  10. // 加载Uri对象
  11. Uri imageUri = getImageUri();
  12. Glide.with(this).load(imageUri).into(imageView);

3.3.2 带有占位图的图片加载

占位图,目的是为在图片还未加载出来的时候,提前展示给用户的一张图片;

  1. Glide.with(this).load(url).placeholder(R.drawable.loading).into(imageView);

还有一种占位图,作为图片加载失败的另一张图片

  1. Glide.with(this).load(url).placeholder(R.drawable.loading).error(R.drawable.error)
  2. .diskCacheStrategy(DiskCacheStrategy.NONE)//关闭Glide的硬盘缓存机制
  3. .into(imageView);
  4. //DiskCacheStrategy.NONE: 表示不缓存任何内容。
  5. //DiskCacheStrategy.SOURCE: 表示只缓存原始图片。
  6. //DiskCacheStrategy.RESULT: 表示只缓存转换过后的图片(默认选项)。
  7. //DiskCacheStrategy.ALL : 表示既缓存原始图片,也缓存转换过后的图片。

3.3.3 静态图片的图片加载

  1. Glide.with(this)
  2. .load(url)
  3. .asBitmap()//只加载静态图片,如果是git图片则只加载第一帧。
  4. .placeholder(R.drawable.loading)
  5. .error(R.drawable.error)
  6. .diskCacheStrategy(DiskCacheStrategy.NONE)
  7. .into(imageView);

3.3.4 动态图片的图片加载

  1. Glide.with(this)
  2. .load(url)
  3. .asGif()//加载动态图片,若现有图片为非gif图片,则直接加载错误占位图。
  4. .placeholder(R.drawable.loading)
  5. .error(R.drawable.error)
  6. .diskCacheStrategy(DiskCacheStrategy.NONE)
  7. .into(imageView);

3.3.5 指定大小图片的图片加载

  1. Glide.with(this)
  2. .load(url)
  3. .placeholder(R.drawable.loading)
  4. .error(R.drawable.error)
  5. .diskCacheStrategy(DiskCacheStrategy.NONE)
  6. .override(100, 100)//指定图片大小
  7. .into(imageView);

3.3.6 不带缓存的图片加载

这里的不带缓存分为两种情况,即:

  • 不带内存缓存

    1. Glide.with(this)
    2. .load(url)
    3. .skipMemoryCache(true) //传入参数为false时,则关闭内存缓存。
    4. .into(imageView);
  • 不带硬盘缓存

    1. Glide.with(this)
    2. .load(url)
    3. .diskCacheStrategy(DiskCacheStrategy.NONE) //关闭硬盘缓存操作
    4. .into(imageView);
    5. //其他参数表示:
    6. //DiskCacheStrategy.NONE: 表示不缓存任何内容。
    7. //DiskCacheStrategy.SOURCE: 表示只缓存原始图片。
    8. //DiskCacheStrategy.RESULT: 表示只缓存转换过后的图片(默认选项)。
    9. //DiskCacheStrategy.ALL : 表示既缓存原始图片,也缓存转换过后的图片。

4. 源码地址

AFL——Android框架学习

发表评论

表情:
评论列表 (有 0 条评论,92人围观)

还没有评论,来说两句吧...

相关阅读