Glide源码剖析系列
- Android Glide源码剖析系列(一)图片加载请求如何感知组件生命周期
- Android Glide源码剖析系列(二)Glide如何管理图片加载请求
- Android Glide源码剖析系列(三)深入理解Glide图片加载流程
- Android Glide源码剖析系列(四)缓存机制及其原理
为什么选择Glide?
- 多种图片格式的缓存,适用于更多的内容表现形式(如Gif、WebP、缩略图、Video)
- 生命周期集成(根据Activity或者Fragment的生命周期管理图片加载请求)Glide可以感知调用页面的生命周期,这就是优势
- 高效处理Bitmap(bitmap的复用和主动回收,减少系统回收压力)
- 高效的缓存策略,灵活(Picasso只会缓存原始尺寸的图片,Glide缓存的是多种规格),加载速度快且内存开销小(默认Bitmap格式的不同,使得内存开销是Picasso的一半)
小结:支持图片格式多;Bitmap复用和主动回收;生命周期感应;优秀的缓存策略;加载速度快(Bitmap默认格式RGB565)
Glide简单使用
Glide.with(this)
.load("https://t7.baidu.com/it/u=3779234486,1094031034&fm=193&f=GIF")
.into(imageView);
源码分析
我们以Gide.with(activity)
方法为切入点开始分析源码
@NonNull
public static RequestManager with(@NonNull FragmentActivity activity) {
return getRetriever(activity).get(activity);
}
只需要一行代码,两步轻松获取RequestManager实例
第一步、getRetriever(activity):获取到RequestManagerRetriever实例
//1. 单例模式创建Glide实例
//2. 获取RequestManagerRetriever实例
@NonNull
private static RequestManagerRetriever getRetriever(@Nullable Context context) {
// Context could be null for other reasons (ie the user passes in null), but in practice it will
// only occur due to errors with the Fragment lifecycle.
Preconditions.checkNotNull(
context,
"You cannot start a load on a not yet attached View or a Fragment where getActivity() "
+ "returns null (which usually occurs when getActivity() is called before the Fragment "
+ "is attached or after the Fragment is destroyed).");
return Glide.get(context).getRequestManagerRetriever(); //分两步分析
}
1.1 使用单例模式获取Glide实例
public static Glide get(@NonNull Context context) {
if (glide == null) {
GeneratedAppGlideModule annotationGeneratedModule =
getAnnotationGeneratedGlideModules(context.getApplicationContext());
synchronized (Glide.class) {
if (glide == null) {
checkAndInitializeGlide(context, annotationGeneratedModule);
}
}
}
return glide;
}
1.2 继续追踪调用链:checkAndInitializeGlide() -> initializeGlide()
private static void initializeGlide(
@NonNull Context context,
@NonNull GlideBuilder builder,
@Nullable GeneratedAppGlideModule annotationGeneratedModule) {
……
Glide glide = builder.build(applicationContext); //建造者模式创建Glide实例
……
Glide.glide = glide;
}
1.3 最终调用GlideBuilder.build()方法构建Glide实例
@NonNull
Glide build(@NonNull Context context) {
//此处省略初始化默认配置信息代码
……
//创建实例并赋值给Glide成员变量requestManagerRetriever
//这里传入的requestManagerFactory是用来创建RequestManager的工厂,第2步分析
RequestManagerRetriever requestManagerRetriever =
new RequestManagerRetriever(requestManagerFactory, experiments);
return new Glide(
context,
engine,
memoryCache,
bitmapPool,
arrayPool,
requestManagerRetriever,
connectivityMonitorFactory,
logLevel,
defaultRequestOptionsFactory,
defaultTransitionOptions,
defaultRequestListeners,
experiments);
}
获取RequestManagerRetriever小结:
- RequestManagerRetriever的创建是在Glide的初始化过程中完成的;
- RequestManagerRetriever构造方法内传入requestManagerFactory,用来创建RequestManager
第二步、get(activity) 创建并返回RequestManager 实例
@NonNull
public RequestManager get(@NonNull FragmentActivity activity) {
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
frameWaiter.registerSelf(activity);
FragmentManager fm = activity.getSupportFragmentManager();
return supportFragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
}
}
2.1 如果当前线程不是主线程,直接转到get(activity.getApplicationContext())中执行;否则继续调用supportFragmentGet()方法
@NonNull
private RequestManager supportFragmentGet(
@NonNull Context context,
@NonNull FragmentManager fm,
@Nullable Fragment parentHint,
boolean isParentVisible) {
SupportRequestManagerFragment current = getSupportRequestManagerFragment(fm, parentHint);
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
// TODO(b/27524013): Factor out this Glide.get() call. (移除此处的Glide.get())
Glide glide = Glide.get(context);
//工厂模式创建requestManager,关于factory见分析2.2
requestManager = factory.build(glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
if (isParentVisible) {
requestManager.onStart();
}
current.setRequestManager(requestManager); //requestManager存储到隐藏的Fragment
}
return requestManager;
}
2.2 RequestManagerFactory 初始化过程
#RequestManagerRetriever.java
//默认RequestManagerFactory
private static final RequestManagerFactory DEFAULT_FACTORY =
new RequestManagerFactory() {
@NonNull
@Override
public RequestManager build(
@NonNull Glide glide,
@NonNull Lifecycle lifecycle,
@NonNull RequestManagerTreeNode requestManagerTreeNode,
@NonNull Context context) {
return new RequestManager(glide, lifecycle, requestManagerTreeNode, context);
}
};
public RequestManagerRetriever(
@Nullable RequestManagerFactory factory, GlideExperiments experiments) {
this.factory = factory != null ? factory : DEFAULT_FACTORY; //默认使用DEFAULT_FACTORY
handler = new Handler(Looper.getMainLooper(), this /* Callback */);
frameWaiter = buildFrameWaiter(experiments);
}
默认使用DEFAULT_FACTORY来创建RequestManager,见2.1requestManager = factory.build(glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
2.3 RequestManager构造方法
#RequestManager.java
RequestManager(
Glide glide,
Lifecycle lifecycle,
RequestManagerTreeNode treeNode,
RequestTracker requestTracker,
ConnectivityMonitorFactory factory,
Context context) {
//省略其他代码
if (Util.isOnBackgroundThread()) {
Util.postOnUiThread(addSelfToLifecycle);
} else {
lifecycle.addListener(this);
}
lifecycle.addListener(connectivityMonitor);
}
private final Runnable addSelfToLifecycle =
new Runnable() {
@Override
public void run() {
lifecycle.addListener(RequestManager.this);
}
};
把当前RequestManager添加到lifecycle,lifecycle是ActivityFragmentLifecycle类型,在SupportRequestManagerFragment 构造方法中创建,后文会介绍SupportRequestManagerFragment类。
重点类总结:
RequestManager implements LifecycleListener
- 操作和管理Glide加载图片的请求
- 实现LifecycleListener接口,根据Activity、Fragment生命周期变化和网络状态来控制图片加载流程
- 由RequestManagerRetriever统一创建和管理,创建时使用工厂模式
RequestManagerRetriever
- 作用是创建和复用RequestManager:使用RequestManagerRetriever.RequestManagerFactory工厂创建RequestManager,复用SupportRequestManagerFragment 中已有的RequestManager
- 在Glide初始化时创建
SupportRequestManagerFragment 无视图的Fragment
- 安全存储RequestManager,由RequestManagerRetriever负责绑定
- 添加到当前Activity,利用SupportRequestManagerFragment 的生命周期变化来控制图片的加载流程
到目前为止,我们了解了大致的框架结构,接下来正式进入到本文的主题
RequestManager如何感知组件的生命周期
我们知道感知生命周期的手段是添加隐藏的SupportRequestManagerFragment,继续查看RequestManagerRetriever#getSupportRequestManagerFragment
源码:
#RequestManagerRetriever.java
/** Pending adds for SupportRequestManagerFragments. */
@VisibleForTesting
//缓存已经添加的隐藏SupportRequestManagerFragment
final Map pendingSupportRequestManagerFragments = new HashMap<>();
@NonNull
private SupportRequestManagerFragment getSupportRequestManagerFragment(
@NonNull final FragmentManager fm, @Nullable Fragment parentHint) {
//1. 检查是否已经添加了隐藏的SupportRequestManagerFragment ,使用HashMap缓存SupportRequestManagerFragment
// 2. 查找FragmentManager 中是否有可以复用的SupportRequestManagerFragment
//如果都没有找到,创建一个新的SupportRequestManagerFragment,
//并且添加到pendings列表&&提交到FragmentManager
SupportRequestManagerFragment current = pendingSupportRequestManagerFragments.get(fm);
if (current == null) {
current = (SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
current = new SupportRequestManagerFragment();
current.setParentFragmentHint(parentHint);
pendingSupportRequestManagerFragments.put(fm, current);
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
}
}
return current;
}
现在隐藏的SupportRequestManagerFragment已经添加成功,继续分析SupportRequestManagerFragment.java
源码
private final ActivityFragmentLifecycle lifecycle;
//构造方法
public SupportRequestManagerFragment() {
this(new ActivityFragmentLifecycle());
}
@VisibleForTesting
@SuppressLint("ValidFragment")
public SupportRequestManagerFragment(@NonNull ActivityFragmentLifecycle lifecycle) {
this.lifecycle = lifecycle;
}
……
@Override
public void onStart() {
super.onStart();
lifecycle.onStart();
}
@Override
public void onStop() {
super.onStop();
lifecycle.onStop();
}
@Override
public void onDestroy() {
super.onDestroy();
lifecycle.onDestroy();
unregisterFragmentWithRoot();
}
新建一个ActivityFragmentLifecycle实例赋值给SupportRequestManagerFragment的lifecycle成员变量,查看ActivityFragmentLifecycle类
class ActivityFragmentLifecycle implements Lifecycle {
//储存LifecycleListener的列表
private final Set lifecycleListeners =
Collections.newSetFromMap(new WeakHashMap());
private boolean isStarted;
private boolean isDestroyed;
/**
* 向lifecycleListeners列表添加LifecycleListener
*/
@Override
public void addListener(@NonNull LifecycleListener listener) {
lifecycleListeners.add(listener);
//添加完成后,根据状态执行对应的回调方法
if (isDestroyed) {
listener.onDestroy();
} else if (isStarted) {
listener.onStart();
} else {
listener.onStop();
}
}
@Override
public void removeListener(@NonNull LifecycleListener listener) {
lifecycleListeners.remove(listener);
}
void onStart() { //遍历执行onStart
isStarted = true;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onStart();
}
}
//与onStart类似
void onStop() {
……
}
void onDestroy() {
……
}
}
使用观察者模式,在组件生命周期发生变化的时候回调相应的操作方法。这一切都是框架帮助咱们完成的,在RequestManager构造函数中把自身加入到ActivityFragmentLifecycle的成员变量lifecycleListeners中。
#RequestManager.java
RequestManager(
Glide glide,
Lifecycle lifecycle,
RequestManagerTreeNode treeNode,
RequestTracker requestTracker,
ConnectivityMonitorFactory factory,
Context context) {
//省略其他代码
if (Util.isOnBackgroundThread()) {
Util.postOnUiThread(addSelfToLifecycle); //切换到主线程执行
} else {
lifecycle.addListener(this); //添加到ActivityFragmentLifecycle成员变量lifecycleListeners
}
lifecycle.addListener(connectivityMonitor);
}
private final Runnable addSelfToLifecycle =
new Runnable() {
@Override
public void run() {
lifecycle.addListener(RequestManager.this); //添加到ActivityFragmentLifecycle成员变量lifecycleListeners
}
};
监听组件生命周期流程汇总:
创建无试图SupportRequestManagerFragment 绑定到当前Activity;
SupportRequestManagerFragment 持有RequestManager实例,RequestManager实例由RequestManagerRetriever创建并传递给SupportRequestManagerFragment ;RequestManager持有ActivityFragmentLifecycle引用,在SupportRequestManagerFragment 构造方法中产生并传递给RequestManager;
RequestManager在构造函数中把自己加入到ActivityFragmentLifecycle.lifecycleListeners列表生命周期同步过程,以Activity调用onStart()为例:
(1)Activity调用onStart()
(2)SupportRequestManagerFragment调用onStart()
@Override
public void onStart() {
super.onStart();
lifecycle.onStart(); //==ActivityFragmentLifecycle.onStart()
}
(3)ActivityFragmentLifecycle#onStart()
void onStart() {
isStarted = true;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onStart(); //==RequestManager.onStart()
}
}
(4)RequestManager#onStart()
@Override
public synchronized void onStart() {
resumeRequests(); //启动图片加载请求
targetTracker.onStart(); //添加到TargetTracker,统一管理targets响应组件生命周期
}
图片加载时感知组件生命周期全过程END
结语
本文我们以一个图片加载请求为例,大致了解了Glide感知组件生命周期的原理,但是实际项目中必然会有许多图片加载请求同时存在,所以必须要有一个机制来统一管理这些图片请求,这样才能在组件生命周期变化时改变这些请求的状态。
关于图片加载请求如何加入到请求列表?Glide又是如何管理这些请求?下一篇文章继续分析!
Android Glide源码解析系列(二)Glide如何管理图片加载请求