先来看下glide
的一般使用方法
Glide.with(context).load(url).into(mImageView);
其中Glide.with(context)
这一步就完成了图片加载时的生命周期绑定,可见glide
调用简单,然而其在背后的逻辑却很复杂,接下来我们从源码的角度去解读glide
如何用一句话完成了这么多事。
我们以context
对象是Activity
为例,进入到Glide.with(context)
这个方法中
RequestManagerRetriever
public RequestManager get(@NonNull Activity activity) {
if (Util.isOnBackgroundThread()) {
// 如果不是主线程,则context对象转为ApplicationContext,然后也不做绑定生命周期的操作,
// 图片加载的生命周期默认为Application的生命周期
return get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
android.app.FragmentManager fm = activity.getFragmentManager();
return fragmentGet(activity, fm, null /*parentHint*/);
}
}
接着进入fragmentGet
方法
private RequestManager fragmentGet(@NonNull Context context,
@NonNull android.app.FragmentManager fm,
@Nullable android.app.Fragment parentHint) {
// 获取到一个无UI的Fragment,用来绑定Activity从而实现生命周期同步
// 因为glide无法直接获取activity的生命周期,通过activity的FragmentManager中加入一个隐藏的fragment,
// 因为fragment与传入的activity生命周期一致,所以只要监听这个RequestManagerFragment就能实现生命周期管理
RequestManagerFragment current = getRequestManagerFragment(fm, parentHint);
RequestManager requestManager = current.getRequestManager();
......
return requestManager;
}
我们具体看下fragment
的创建过程
RequestManagerFragment getRequestManagerFragment(
@NonNull final android.app.FragmentManager fm, @Nullable android.app.Fragment parentHint) {
// 由于这个Fragment是个无UI的Fragment,可以通过findFragmentByTag(FRAGMENT_TAG)去查找这个RequestManagerFragment
// 但如果第一次进来,current就是null,如果已经创建过,可以通过fm对象找到已有的fragment对象
// 无UI查找Fragment参考文章 http://blog.csdn.net/llp1992/article/details/41828237
RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
current = pendingRequestManagerFragments.get(fm);
if (current == null) {
// 初始化RequestManagerFragment并且绑定FRAGMENT_TAG放入FragmentManager
current = new RequestManagerFragment();
......
}
}
return current;
}
接着我们进入RequestManagerFragment
的构造方法中查看初始化的时候做了些什么
public class SupportRequestManagerFragment extends Fragment {
public SupportRequestManagerFragment() {
// 初始化Fragment的时候也顺便初始化了ActivityFragmentLifecycle
this(new ActivityFragmentLifecycle());
}
@SuppressLint("ValidFragment")
public SupportRequestManagerFragment(ActivityFragmentLifecycle lifecycle) {
// lifecycle赋值
this.lifecycle = lifecycle;
}
/**
* 在构造方法中{@link #SupportRequestManagerFragment(ActivityFragmentLifecycle)}
* 初始化lifecycle
*/
ActivityFragmentLifecycle getGlideLifecycle() {
return 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();
}
}
我们可以看下上面这个类的部分代码,在初始化Fragment
的时候也顺带初始化了ActivityFragmentLifecycle
,并赋值给lifecycle
,在fragment
的生命周期方法中,比如onStart
方法中,调用了lifecycle.onStart()
,由于fragment
和绑定的activity生命周期基本一样,这样的话lifecycle
对象也就带有刚开始传入Glide.with(context)
这个context
对象的生命周期,可以通过fragment
对象的getGlideLifecycle()
方法获取到这个带有生命周期的自定义类的对象。
到这里,基本就知道了glide
怎么去获取到当前上下文对象的生命周期变化,接下去我们继续分析,glide
获取到生命周期后去做了些什么事情。
首先来看下这个自定义的生命周期自定义类
class ActivityFragmentLifecycle implements Lifecycle {
@Override
public void addListener(LifecycleListener listener) {
lifecycleListeners.add(listener);
if (isDestroyed) {
listener.onDestroy();
} else if (isStarted) {
listener.onStart();
} else {
listener.onStop();
}
}
@Override
public void removeListener(LifecycleListener listener) {
lifecycleListeners.remove(listener);
}
void onStart() {
isStarted = true;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onStart();
}
}
void onStop() {
isStarted = false;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onStop();
}
}
void onDestroy() {
isDestroyed = true;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onDestroy();
}
}
}
public interface Lifecycle {
void addListener(LifecycleListener listener);
void removeListener(LifecycleListener listener);
}
ActivityFragmentLifecycle
实现了Lifecycle
,对外暴露一个addListener
方法,可以监听生命周期的变化。到这里,监听生命周期的准备工作都已经完成,就等其他想要使用的地方去实现这个监听器了,所以我们回过头去看下哪里实现了这个监听器。
接下来我们回到上文中的fragmentGet
方法,刚刚看了部分代码,现在我把这个方法的全部代码贴出来
private RequestManager fragmentGet(@NonNull Context context,
@NonNull android.app.FragmentManager fm,
@Nullable android.app.Fragment parentHint) {
// 获取到一个无UI的Fragment,用来绑定Activity从而实现生命周期同步
// 因为glide无法直接获取activity的生命周期,通过activity的FragmentManager中加入一个隐藏的fragment,
// 因为fragment与传入的activity生命周期一致,所以只要监听这个RequestManagerFragment就能实现生命周期管理
RequestManagerFragment current = getRequestManagerFragment(fm, parentHint);
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
// 初始化了图片加载引擎等内容,为后面的图片加载做准备
Glide glide = Glide.get(context);
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
current.setRequestManager(requestManager);
}
return requestManager;
}
上面我们用大篇幅解析了这一行代码 RequestManagerFragment current = getRequestManagerFragment(fm, parentHint)
,接下去我们接着走下去。接着执行 RequestManager requestManager = current.getRequestManager()
,当第一次执行 current.get
方法的时候,返回的 requestManager
对象是null
,所以我们重点分析下if
里面的代码块。
我们进入factory.build(glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context)
方法中
public interface RequestManagerFactory {
@NonNull
RequestManager build(
@NonNull Glide glide,
@NonNull Lifecycle lifecycle,
@NonNull RequestManagerTreeNode requestManagerTreeNode,
@NonNull Context context);
}
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) {
// 在这里初始化RequestManager
return new RequestManager(glide, lifecycle, requestManagerTreeNode, context);
}
};
其中factory
在RequestManagerRetriever
构造方法中被赋值:this.factory = factory != null ? factory : DEFAULT_FACTORY
,故 factory.build 最终执行的是return new RequestManager(glide, lifecycle, requestManagerTreeNode, context)
。其中lifecycle
正是我们前面创建fragment
生成的带有生命周期的自定义类。
我们进入RequestManager
的构造方法,查看下RequestManager
整个类的关键代码
public class RequestManager implements LifecycleListener {
RequestManager(
Glide glide,
Lifecycle lifecycle,
RequestManagerTreeNode treeNode,
RequestTracker requestTracker,
ConnectivityMonitorFactory factory,
Context context) {
this.glide = glide;
this.lifecycle = lifecycle;
this.treeNode = treeNode;
this.requestTracker = requestTracker;
this.context = context;
if (Util.isOnBackgroundThread()) {
mainHandler.post(addSelfToLifecycle);
} else {
// RequestManager 实现了LifecycleListener,然后和lifecycle实现了绑定
lifecycle.addListener(this);
}
}
@Override
public void onStart() {
resumeRequests();
targetTracker.onStart();
}
@Override
public void onStop() {
pauseRequests();
targetTracker.onStop();
}
@Override
public void onDestroy() {
targetTracker.onDestroy();
for (Target<?> target : targetTracker.getAll()) {
clear(target);
}
targetTracker.clear();
requestTracker.clearRequests();
lifecycle.removeListener(this);
lifecycle.removeListener(connectivityMonitor);
mainHandler.removeCallbacks(addSelfToLifecycle);
glide.unregisterRequestManager(this);
}
}
RequestManager
从类名来看,应该就是请求管理类,它自身实现了LifecycleListener
,在自身的构造方法中,和lifecycle
进行了绑定,这样我们先前初始化的fragment
的生命周期就在这里实现了监听,我们可以看下RequestManager
生命周期方法中的一些代码,resumeRequests()
、pauseRequests()
,顾名思义,他在执行相应生命周期的时候做了重新发送请求、暂停请求、销毁请求等操作。
到这里,我们就对glide
的生命周期有了完整的了解,图片在加载时,会根据传入context
对象的生命周期变化而做出暂停、销毁请求等操作,其中实现的主要原理就是glide
生成了一个没有UI的Fragment
同步context
对象的生命周期,然后对这个自定义的Fragment
进行监听,从而处理其他加载逻辑。
网友评论