简单使用一下
Glide.with(context).load(url).into(imageView)
1、with(xxx)
该参数是可以是 ApplicationContext、Activity 或 Fragment,是告诉Glide组件应该依附在哪个组件上
如果传入的是应用全局ApplicationContext那么它的生命周期和整个应用是保持一致的,Glide通过单例持有全局RequestManager进行管理,它没有生命周期回调,操作起来不方便,如果加载图片至Activity的ImageView,但此Activity被销毁了,RequestManager仍旧对ImageView进行赋值会导致空对象引用报错
如果传入的是Activity 或 Fragment则会在其基础上附加一个没有UI的隐藏Fragment
(1)隐藏的Fragment
这个隐藏的Fragment不会显示任何东西,它主要的作用是监听持有者的生命周期回调(onCreate、onStart()、onStop()、onDestroy()等),当持有者调用这些方法时,该隐藏Fragment就会收到通知,随之调用对应RequestManager的方法
(2)RequestManager 是什么
RequestManager是单例的,如果已经被初始化过会直接返回确保当前Activity只有一个RequestManager 来管理其生命周期内的图片请求,如果不存在则会创建一个SupportRequestManagerFragment通过 FragmentManager 将这个新创建的隐藏 Fragment 添加到宿主上,该Fragment会创建一个新的RequestManager 实例,并将其持有,之后所有的处理都是交给RequestManager,它就像一个管家,专门为你处理图片,下面是写的很草率的版本
class NoUIRequestManagerFragment : Fragment() {
// 这个就是管家
private var requestManager: RequestManager? = null
override fun onCreate(savedInstanceState: Bundle?) {
if(requestManager == null) {
requestManager = RequestManager()
}
}
/** 其他生命周期 ...
// 让外部可以获取它所持有的 RequestManager 实例
fun getRequestManager(): RequestManager {
return requestManager
?: throw IllegalStateException("RequestManager not initialized")
}
}
在外部初始化NoUIRequestManagerFragment没有UI的Fragment后,可以使用
fun getRequestManager() : RequestManager {
val FRAGMENT_TAG = "xxx" // 1. 尝试从FragmentManager中查找已存在的 NoUIRequestManagerFragment
var fragment = supportFragmentManager.findFragmentByTag(FRAGMENT_TAG) as? NoUIRequestManagerFragment
if(fragment == null){
fragment = NoUIRequestManagerFragment()
supportFragmentManager
.beginTransaction()
.add(fragment, FRAGMENT_TAG) // 将 Fragment 添加到 Activity
.commitNowAllowingStateLoss() // 立即提交,允许在状态丢失后提交
}
return fragment.getRequestManager()
}
override fun onCreate(savedInstanceState: Bundle?) {
// 类似Glide.with(context),可以用imageLoader加载图片了
val imageLoader = getRequestManager()
}
/** 其他生命周期 ...
2、load(url)
简单讲就是定义需要加载的资源,通过ModelLoader处理不同数据源
(1)缓存查找:内存、磁盘
(2)数据获取:启动DataFetcher去获取图片,这个过程是异步的
3、into(imageView)
经过解码、转换(处理图片API)后的最终 Bitmap 会被封装成一个 Drawable,然后通过主线程回调,设置到目标 ImageView 上
结尾讲讲load中的两种查找优化方式
内存缓存(LRU):使用LinkedHashMap,它除了维护键值对的哈希表结构外,还维护了一个双向链表来记录元素的插入顺序或访问顺序,当 accessOrder 设置为 true 时,LinkedHashMap 会按照访问顺序来维护链表:每当一个元素被访问(get() 或 put()),它就会被移动到链表的尾部,这样头部永远存储访问次数最少的元素,当超过维护的最大容量时,就会从头部移除元素
磁盘缓存(DiskLRU):指定一个目录进行存储,通过访问时间维护判断哪些是最近最少使用的,当在空间不足时进行淘汰
先通过内存缓存查找,若未找到再通过磁盘缓存查找,最后通过网络请求访问
谢谢看到这里,Glide雀食好用