ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
***** **开始使用** [TOC=6] # 1. 为什么使用Glide? **1. 首先图片加载框架存在的问题** 需要自己封装HTTPURLConnection 需要自己封装三级缓存 需要自己ListView图片错位问题 。。。存在很多问题 那么这些问题怎么解决呢? 有一帮哥们搞了一下框架如: ~~~ afinal的afinalBitmap Xutils的BitmapUtils universalImageLoader square的picasso google推荐的glide FaceBook推出的fresco ~~~ **2. 为什么要选择Glide** 首先来分析下,一个优秀的图片库应该具有什么样的特性? * 易用性。这对于绝大多数开源库而言,都是需要做到的,但这又是很难的一方面。举个例子,图片库涉及到网络、缓存、编码等等各个环节,但这些环节不应该让所有用户都知晓,应该拿捏到这种力度:用户可以不知晓,有需求的可以进行自定义。开源库可能有很多类用户可以涉及,但最好有统一的外观(Facade Pattern),Glide 在这点上就做得足够好。 * 扩展性。需求这东西嘛,总是比天气变化快多了,设计的开源库就必须得有很好的扩展性。无论是 Volley,Glide 还是其他知名开源库,在这点上都做得很好。关键在于抽象::不变的与变化的::,变化的是 `网络`,`编码`和`缓存`等等模块,不变的是它们之间是如何衔接的。在合理的抽象建模下,还是很容易高的扩展性的。 * 高性能与低占用。这是图片库最核心的部分,也是最难的部分。难点在于三个方面。 * 内存受限。受限于移动终端的低内存,如果占用内存过大,会使得分配变得低效,不稳定。如果复用不给力,高频率的分配内存,会导致GC频繁,从而卡顿。 * 流畅性。Android 系统中的图片常用于 RecyclerView,GridView 中,这些控件往往展示着大量的图片,在这些图片频繁加载、编码等等情况下,保证滑动流畅呢? * 生命周期。Android的UI组件有各个周期,Glide 要在尽可能少入侵代码的前提下,参与到生命周期里面去,从而合理地分配和释放资源。 Glide完全具备这些特点,这么优秀的框架我们当然要学习。 # 2. 什么是Glide? ![](https://box.kancloud.cn/7fcd9f0d30b2314c914de3cc0b7c6e09_800x240.png) Glide是Google推出的优秀的用来实现图片异步加载的框架。 # 3. 下载Glide ~~~ dependencies { implementation 'com.github.bumptech.glide:glide:4.9.0' } ~~~ # 4. 设置 ## 1. 网络权限 如果你计划从 URL 或一个网络连接中加载数据,你需要添加`INTERNET`和`ACCESS_NETWORK_STATE`权限到你的`AndroidManifest.xml`中: ~~~ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="your.package.name" <uses-permission android:name="android.permission.INTERNET"/> <!-- Allows Glide to monitor connectivity status and restart failed requests if users go from a a disconnected to a connected network state. --> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <application> ... </application> </manifest> ~~~ 从技术上讲,`ACCESS_NETWORK_STATE`对于 Glide 加载 URL 并不是必需的,但是它将帮助 Glide 处理*片状网络(flaky network)*和飞行模式。请继续阅读下面的连接监视章节以了解详情。 **连接监听** 如果你正在从 URL 加载图片,Glide 可以自动帮助你处理片状网络连接:它可以监听用户的连接状态并在用户重新连接到网络时重启之前失败的请求。如果 Glide 检测到你的应用拥有`ACCESS_NETWORK_STATE`权限,Glide 将自动监听连接状态而不需要额外的改动。 你可以通过检查`ConnectivityMonitor`日志标签来验证 Glide 是否正在监听网络状态: ~~~ adb shell setprop log.tag.ConnectivityMonitor DEBUG ~~~ 如果你成功添加了`ACCESS_NETWORK_STATE`权限,你将在 logcat 中看到类似这样的日志: ~~~ 11-18 18:51:23.673 D/ConnectivityMonitor(16236): ACCESS_NETWORK_STATE permission granted, registering connectivity monitor 11-18 18:48:55.135 V/ConnectivityMonitor(15773): connectivity changed: false 11-18 18:49:00.701 V/ConnectivityMonitor(15773): connectivity changed: true ~~~ 而如果权限缺失,你将看到一条错误: ~~~ 11-18 18:51:23.673 D/ConnectivityMonitor(16236): ACCESS_NETWORK_STATE permission missing, cannot register connectivity monitor ~~~ ## 2. 本地存储(Local Storage) 要从本地文件夹或 DCIM 或图库中加载图片,你将需要添加`READ_EXTERNAL_STORAGE`权限: ~~~ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="your.package.name" <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <application> ... </application> </manifest> ~~~ 而如果要使用[`ExternalPreferredCacheDiskCacheFactory`](https://muyangmin.github.io/glide-docs-cn/javadocs/431/com/bumptech/glide/load/engine/cache/ExternalPreferredCacheDiskCacheFactory.html)来将 Glide 的缓存存储到公有 SD 卡上,你还需要添加`WRITE_EXTERNAL_STORAGE`权限: ~~~ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="your.package.name" <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <application> ... </application> </manifest> ~~~ # 5. 使用Glide加载网络图片 **基本用法** 多数情况下,使用Glide加载图片非常简单,一行代码足矣: ~~~ Glide.with(fragment) .load(myUrl) .into(imageView); ~~~ 取消加载同样很简单: ~~~ Glide.with(fragment).clear(imageView); ~~~ 尽管及时取消不必要的加载是很好的实践,但这并不是必须的操作。实际上,当[`Glide.with()`](https://muyangmin.github.io/glide-docs-cn/javadocs/400/com/bumptech/glide/Glide.html#with-android.app.Fragment-)中传入的 Activity 或 Fragment 实例销毁时,Glide 会自动取消加载并回收资源。 # 6. Generated API 1. 添加 Glide 注解处理器的依赖: ~~~ dependencies { annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0' } ~~~ 参阅[下载和设置](https://muyangmin.github.io/glide-docs-cn/doc/download-setup.html)页面了解更多。 2. 在 Application 模块中包含一个[`AppGlideModule`](https://muyangmin.github.io/glide-docs-cn/javadocs/400/com/bumptech/glide/module/AppGlideModule.html)的实现: ~~~ package com.example.myapp; import com.bumptech.glide.annotation.GlideModule; import com.bumptech.glide.module.AppGlideModule; @GlideModule public final class MyAppGlideModule extends AppGlideModule {} ~~~ 你不必去重写`AppGlideModule`中的任何一个方法。子类中完全可以不用写任何东西,它只需要继承`AppGlideModule`并且添加`@GlideModule`注解。 [`AppGlideModule`](https://muyangmin.github.io/glide-docs-cn/javadocs/400/com/bumptech/glide/module/AppGlideModule.html)的实现必须使用[`@GlideModule`](https://muyangmin.github.io/glide-docs-cn/javadocs/400/com/bumptech/glide/annotation/GlideModule.html)注解标记。如果注解不存在,该 module 将不会被 Glide 发现,并且在日志中收到一条带有`Glide`tag 的警告,表示 module 未找到。