1. Glide的优点
2. 生命周期绑定原理
3. 缓存原理
1. Glide的优点
-
使用简单,链式调用比较方便
Glide.with(context) .load(uri) .into(imageView);
-
占用内存较小
默认使用RGB_565格式,是Picasso的内存占用的一半(Picasso使用RGB_8888)
-
无代码侵入
相对Picasso来说,接入很简单,无需将ImageView替代为自定义View,也不需要其他配置,只需要将库引入即可
-
支持gif
ImageLoader不支持gif图片加载
-
缓存优化
- 支持内存分级缓存:正在使用的图片,弱引用缓存;已使用过的图片LruCache缓存
- Glide会为不同的ImageView尺寸缓存不同尺寸的图片
-
与Activity生命周期绑定,不会出现内存泄露
2. 生命周期绑定原理
-
实现原理
基于在Activity中添加无UI的Fragment,通过Fragment接收Activity传递的生命周期。Fragment和RequestManager基于LifeCycle接口建立联系,并传递生命周期事件,实现生命周期感知。
-
如何绑定生命周期
在调用
Glide.with(Activity activity)
的时候,我们跟一下流程,核心代码下面看一下。// with入口 public static RequestManager with(@NonNull FragmentActivity activity) { return getRetriever(activity).get(activity); } // 此处拿到对应的 FragmentManager,为生成Fragment做准备 public RequestManager get(@NonNull FragmentActivity activity) { if(Util.isOnBackgroundThread()) { return this.get(activity.getApplicationContext()); } else { assertNotDestroyed(activity); android.support.v4.app.FragmentManager fm = activity.getSupportFragmentManager(); return this.supportFragmentGet(activity, fm, (Fragment)null, isActivityVisible(activity)); } } private RequestManager supportFragmentGet(@NonNull Context context, @NonNull android.support.v4.app.FragmentManager fm, @Nullable Fragment parentHint, boolean isParentVisible) { // current就是一个无UI的Fragment实例 SupportRequestManagerFragment current = this.getSupportRequestManagerFragment(fm, parentHint, isParentVisible); RequestManager requestManager = current.getRequestManager(); if(requestManager == null) { Glide glide = Glide.get(context); // 将Fragment的LifeCycle传入RequestManager中,建立起来联系 requestManager = this.factory.build(glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context); current.setRequestManager(requestManager); } return requestManager; } //RequestManager的构造方法中绑定LifeCycle,将自己的引用存入LifeCycle,调用LifeCycle的生命周期时进行回调 lifecycle.addListener(this);
稍微整理一下就是:
1. Glide绑定Activity时,生成一个无UI的Fragment 2. 将无UI的Fragment的LifeCycle传入到RequestManager中 3. 在RequestManager的构造方法中,将RequestManager存入到之前传入的Fragment的LifeCycle,在回调LifeCycle时会回调到Glide的相应方法
-
如何通过Fragment的生命周期回调调用Glide的对应方法
通过Fragment的回调调用到Glide的RequestManager的对应的方法即可执行不同的操作,主要绑定的三个方法为:
onStart()
,onStop()
,onDestroy()
回调的源码也翻一下
//RequestManager的构造方法中绑定LifeCycle,将自己的引用存入LifeCycle,调用LifeCycle的生命周期时进行回调 //这个this是RequestManager的实例 lifecycle.addListener(this); // onDestory的回调示例 void onDestroy() { this.isDestroyed = true; Iterator var1 = Util.getSnapshot(this.lifecycleListeners).iterator(); while(var1.hasNext()) { LifecycleListener lifecycleListener = (LifecycleListener)var1.next(); lifecycleListener.onDestroy(); } } //下面看一下RequestManager里面的onDestory方法,里面主要做一些解绑和清除操作 public void onDestroy() { this.targetTracker.onDestroy(); Iterator var1 = this.targetTracker.getAll().iterator(); while(var1.hasNext()) { Target<?> target = (Target)var1.next(); this.clear(target); } this.targetTracker.clear(); this.requestTracker.clearRequests(); this.lifecycle.removeListener(this); this.lifecycle.removeListener(this.connectivityMonitor); this.mainHandler.removeCallbacks(this.addSelfToLifecycle); this.glide.unregisterRequestManager(this); }
3. 缓存原理
-
几种缓存模式
以下几个属性是4.7.0版本的
- DiskCacheStrategy.ALL:原始图片和转换过的图片都缓存
- DiskCacheStrategy.RESOURCE:只缓存原始图片
- DiskCacheStrategy.NONE:不缓存
- DiskCacheStrategy.DATA:只缓存使用过的图片
-
内存缓存
这部分逻辑较多,记住结论就行,正在使用的图片使用的是弱引用缓存,使用完成后,添加到LruCache缓存
-
磁盘缓存
默认缓存使用过的分辨率图片,使用DiskLruCache来做的磁盘缓存
主要就是根据配置的策略去读取对应的缓存,原始数据缓存是在数据请求完成时,转换过的图片是在对图片进行transform转换后缓存。