文章目录
- 前言
- 简要说明过程
- 怎么完成绑定
- 核心类的作用
- 总结
前言
Glide 是非常强大的图片加载框架,基本在所有的面试中都会被问到,而问得最多的可能就是如何与页面生命周期的绑定,针对这点,我做了一下整理,我自己也开了一个项目,关于Android的面试题,有需要的可以进来看看https://github.com/shenshizhong/AndroidIQ
简单说明过程
对整个过程有个大体的印象,不然看着源码就找不着北了。
绑定的大体过程:Glide -> RequestManagerRetriever -> RequestManagerFragment
-> ActivityFragmentLifecycle -> RequestManager -> RequestTracker
怎么完成绑定
这是最关键的,这里我们主要是以Activity 为过程,来了解绑定,其他的可以以此类推。
首先我们我们从最熟悉的使用开始 Glide.with(imageView.getContext())
Glide
public RequestManager get(@NonNull Context context) {
if (context == null) {
throw new IllegalArgumentException("You cannot start a load on a null Context");
} else if (Util.isOnMainThread() && !(context instanceof Application)) {
if (context instanceof FragmentActivity) {
return get((FragmentActivity) context);
} else if (context instanceof Activity) { // 这是我们要分析的,其他差不多,以此类推
return get((Activity) context);
} else if (context instanceof ContextWrapper) {
return get(((ContextWrapper) context).getBaseContext());
}
}
return getApplicationManager(context);
}
接着进入get方法中查看
RequestManagerRetriever
public static RequestManager with(@NonNull Activity activity) {
return getRetriever(activity).get(activity);
}
public RequestManager get(@NonNull Activity activity) {
//判断是不是在后台运行,如果是的话,使用整个应用为生命周期
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
android.app.FragmentManager fm = activity.getFragmentManager();
return fragmentGet(
activity, fm, /*parentHint=*/ null, isActivityVisible(activity)); //这是我们要看的
}
}
这里我们只要是看页面的生命周期,所以我们看fragmentGet 里面的内容
RequestManagerRetriever # fragmentGet
private RequestManager fragmentGet(@NonNull Context context,
@NonNull android.app.FragmentManager fm,
@Nullable android.app.Fragment parentHint,
boolean isParentVisible) {
//创建一个空的 Fragment 对象,主要用来监听页面的生命周期
RequestManagerFragment current = getRequestManagerFragment(fm, parentHint, isParentVisible);
RequestManager requestManager = current.getRequestManager(); //创建一个 RequestManager 对象
if (requestManager == null) {
// TODO(b/27524013): Factor out this Glide.get() call.
Glide glide = Glide.get(context);
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);//将 Fragment 的生命周期传递给 RequestManager
current.setRequestManager(requestManager); //将RequestManager 传递给 Fragment
}
return requestManager;
}
private RequestManagerFragment getRequestManagerFragment(@NonNull final android.app.FragmentManager fm, @Nullable android.app.Fragment parentHint,boolean isParentVisible) {
RequestManagerFragment current = (RequestManagerFragment)fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
current = pendingRequestManagerFragments.get(fm);
if (current == null) {
current = new RequestManagerFragment(); //可以看出,所要创建的Fragment 的实现类是RequestManagerFragment
current.setParentFragmentHint(parentHint);
if (isParentVisible) {
current.getGlideLifecycle().onStart();
}
pendingRequestManagerFragments.put(fm, current);
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
}
}
return current;
}
这里主要是创建一个空的Fragment 和 RequestManager 对象,然后将 Fragment 的生命周期传递给 RequestManager,把RequestManager 传递给 Fragment。
到这里主要完成的事情:通过RequestManagerRetriever 将Fragment 和 RequestManager联系起来了。下面就具体说下,怎么绑定了。
------------具体绑定过程----------
首先从新建的空Fragment说起,它的具体实现类是RequestManagerFragment,在创建的时候,同时创建了ActivityFragmentLifecycle
RequestManagerFragment
public RequestManagerFragment() {
this(new ActivityFragmentLifecycle());
}
@VisibleForTesting
@SuppressLint("ValidFragment")
RequestManagerFragment(@NonNull ActivityFragmentLifecycle lifecycle) {
this.lifecycle = lifecycle;
}
以下就是关键代码了,这里头会在生命周期中,调用ActivityFragmentLifecycle的相应方法。
RequestManagerFragment
@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的几个关键方法
public void addListener(@NonNull LifecycleListener listener) {
lifecycleListeners.add(listener);
if (isDestroyed) {
listener.onDestroy();
} else if (isStarted) {
listener.onStart();
} else {
listener.onStop();
}
}
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();
}
}
从上面的代码中,我们看到调用了 lifecycleListener 的相应方法,那么这个lifecycleListener 实现类是谁呢?我们看到 lifecycleListener.onStart(); 这个 lifecycleListener 其实是从lifecycleListeners 的容器中拿出来的,那lifecycleListeners 又是在addListener 进行添加的。
这个时候我们想知道,addListener 被谁调用了,点方法可以看到调用的类(AS提供的),我们发现是RequestManager,是的,我们看到了如下的代码:
public class RequestManager implements LifecycleListener,ModelTypes<RequestBuilder<Drawable>> {
...
RequestManager(
Glide glide,
Lifecycle lifecycle,
RequestManagerTreeNode treeNode,
RequestTracker requestTracker,
ConnectivityMonitorFactory factory,
Context context) {
···
if (Util.isOnBackgroundThread()) {
mainHandler.post(addSelfToLifecycle);
} else {
lifecycle.addListener(this); //这里添加了
}
lifecycle.addListener(connectivityMonitor);
setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());
glide.registerRequestManager(this);
}
这个时候我们回想下之前看过的代码,其实我们在创建requestManager对象的时候, current.getGlideLifecycle() 已经把fragment 中的 ActivityFragmentLifecycle 传进去了。代码如下:
RequestManagerRetriever # fragmentGet
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
好了,我们清楚了,ActivityFragmentLifecycle 的方法会调用RequestManager 的方法,比如上面的 lifecycleListener.onStart();其实调用的就是RequestManager #onStart。那么我们看下RequestManager的类:
RequestManager
public void onStart() {
resumeRequests();
targetTracker.onStart();
}
public void onStop() {
pauseRequests();
targetTracker.onStop();
}
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);
}
我们就看onStart 吧,其他方法类推,他会调用pauseRequests(); 看下里头做了什么?
RequestManager
public void resumeRequests() {
Util.assertMainThread();
requestTracker.resumeRequests();
}
继续点 requestTracker.resumeRequests(); 我们看到了下面的代码
RequestTracker
public void resumeRequests() {
isPaused = false;
for (Request request : Util.getSnapshot(requests)) {
if (!request.isComplete() && !request.isRunning()) {
request.begin(); //这就是请求的开始
}
}
pendingRequests.clear();
}
request.begin(); 是进行请求的,也就是我们glide 进行的操作。到这里,就完成了生命周期开始的绑定,然后看其他的方法,比如onStop(),onDestroy(),其实就是执行Glide的停止和结束的操作了。这个绑定的过程就是如此了,看完是不是舒畅了一下呢。
核心类的作用
- RequestManagerFragment:实现一个无UI的fragment。
- ActivityFragmentLifecycle:无UI的fragment通过它,去调用RequestManager
- RequestManager:实现关键的几个方法,去调用glide 的操作
- RequestManagerRetriever:作为一个桥梁,将RequestManagerFragment
和RequestManager给联系起来
总结:
总体的过程就是,空RequestManagerFragment 的生命周期调用 ActivityFragmentLifecycle,然后ActivityFragmentLifecycle 调用 RequestManager ,RequestManager 再去调用RequestTracker 的glide操作,最终实现gilde的操作,能够根据页面的生命周期做相应的处理。
如果对你有一点点帮助,那是值得高兴的事情。:)
我的csdn:http://blog.csdn.net/shenshizhong
我的简书:http://www.jianshu.com/u/345daf0211ad