Glide 4.12 框架源码中的生命周期设计
Posted hymKing
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Glide 4.12 框架源码中的生命周期设计相关的知识,希望对你有一定的参考价值。
在上一篇文章《最新源码Glide4.12框架之加载图片流程源码分析》中,我们主要做了对于通过Glide.with(this).load(url).into(target)的调用图片加载流程的的源码分析,以及对加载流程图的梳理。
本篇文章主要对Glide图片框架的生命周期感知进行源码分析,体会Glide是如何做到感知Activity、Fragment的生命周期并控制自身图片加载过程的生命周期的。
一、初识Glide图片加载生命周期
- 深度的生命周期集成,以确保仅优先处理活跃的Fragment和Activity的请求,并有利于应用在必要时释放资源以避免在后台时被杀掉。
上述文字是Glide官方文档中对Glide的生命周期的介绍,Glide图片加载框架的加载行为,会随着Activity、Fragment生命周期的变化而变化,当一个Activity或者Fragment销毁的时候,生命周期的回调函数被调用,触发Glide图片加载的停止,可以避免内存泄漏,是对手机系统资源利用效率的提升。
二、生命周期实现详解
还是从上面一篇文章中最基本的使用Demo入手:
public class MainActivity extends AppCompatActivity
String url = "";
ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
imageView = findViewById(R.id.img_glide);
//通过链式调用的方式加载一张图片
Glide.with(this).load(url).into(imageView);
Glide.with方法的重载函数有如下几种情况:
public class Glide implements ComponentCallbacks2
/**使用上下文启动的任何请求将应用Application级别的options,不会根据生命周期时间启动和停止
*这个方法适用于在普通的Fragment、Activity之外的使用场景,比如在Service中、notification
*中的缩略图
*/
public static RequestManager with(@NonNull Context context)
return getRetriever(context).get(context);
/**启动一个加载绑定在Activity的生命周期上,并使用Activity的默认options
*/
public static RequestManager with(@NonNull Activity activity)
return getRetriever(activity).get(activity);
/**启动一个加载绑定在FragmentActivity的生命周期上,并使用FragmentActivity的默认options
*/
public static RequestManager with(@NonNull FragmentActivity activity)
return getRetriever(activity).get(activity);
/**启动一个加载绑定在Fragment的生命周期上,并使用Fragment的默认options
*/
public static RequestManager with(@NonNull Fragment fragment)
return getRetriever(fragment.getContext()).get(fragment);
上面四个with重载方法的文档注释部分都做中文翻译,显然with(context)的情况,我们就不用分析了。另外的三个重载函数表达都是和Activity、Fragment生命周期的绑定,Fragment的生命周期本质上是有Activity的生命周期函数驱动的。所以接下来,我们只要分析with(Activity)的实现源码分析,其它两种情况是类比相似的。RequestManagerRetriever.get()方法的调用:
public class RequestManagerRetriever implements Handler.Callback
@SuppressWarnings("deprecation")
@NonNull
public RequestManager get(@NonNull Activity activity)
//非主线程
if (Util.isOnBackgroundThread())
//返回和applicationContext关联的RequestManager
return get(activity.getApplicationContext());
else if (activity instanceof FragmentActivity)
//FragmentActivity 调用此方法
return get((FragmentActivity) activity);
else
assertNotDestroyed(activity);
frameWaiter.registerSelf(activity);
android.app.FragmentManager fm = activity.getFragmentManager();
//Activity最终会调用此方法
return fragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
public RequestManager get(@NonNull FragmentActivity activity)
if (Util.isOnBackgroundThread())
return get(activity.getApplicationContext());
else
assertNotDestroyed(activity);
frameWaiter.registerSelf(activity);
//fragment管理者对象
FragmentManager fm = activity.getSupportFragmentManager();
//FragmentAcitivty最终会调用此方法
return supportFragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
2.1 创建空fragment并注入requestManger
通过上述的代码注释的分析,最终都会调用到supportFragmentGet(),在这个方法中完成了生命周期的绑定过程,并且在符合条件的情况下,调用RequestManager的onStart方法。
@NonNull
private RequestManager supportFragmentGet(
@NonNull Context context,
@NonNull FragmentManager fm,
@Nullable Fragment parentHint,
boolean isParentVisible)
//查看supportRequest的源码,文档注释部分说明如下:
/**一个无view的fragment用于安全的持有requestManager用于开始、停止和管理glide的请求
*这个fragment作为子组件被添加到Activity或是Fragment上*/
SupportRequestManagerFragment current = getSupportRequestManagerFragment(fm, parentHint);
//获取持有的requestManager
RequestManager requestManager = current.getRequestManager();
//如果requestManager为空
if (requestManager == null)
Glide glide = Glide.get(context);
//通过工厂方法创建一个requestManger
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
//这里实际就是isActivityVisable
if (isParentVisible)
//requestManger调用onStart
requestManager.onStart();
//且把当前的fragment中注入requestManger,和requestManager进行绑定
current.setRequestManager(requestManager);
return requestManager;
SupportRequestManagerFragment 是一个无view的Fragment,通过getSupportRequestManagerFragment方法获取和创建,我们看一下创建和获取的源代码:
public class RequestManagerRetriever implements Handler.Callback
@NonNull
private SupportRequestManagerFragment getSupportRequestManagerFragment(
@NonNull final FragmentManager fm, @Nullable Fragment parentHint)
//根据tag从fragmentManger中获取
SupportRequestManagerFragment current =
(SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null)
//没有获取达到从内存的一个map集合中获取
current = pendingSupportRequestManagerFragments.get(fm);
if (current == null)
//还没有获取到,则直接new一个fragment,在上段源码注释中已经说明,此是一个无view的frag
current = new SupportRequestManagerFragment();
current.setParentFragmentHint(parentHint);
//添加到内存map集合中,待用。相同的Activity中加载图片的时候,就可以获取到了,主要依赖于
//fragmentManger对象是否相同,查询条件传入的参数就是fm实例
pendingSupportRequestManagerFragments.put(fm, current);
//添加、提交
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
//删除临时临时映射关系,不用管这块
handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
return current;
从这段源码中可以看到,同一个activity中加载不同图片的时候,空fragment对象实例是可以重复使用的。通过pendingSupportRequestManagerFragments这个map集合进行维护,也可以避免重复创建。
2.2 生命周期的的绑定、监听过程实现分析
从上段的分析,我们知晓创建的空fragment就是用于生命周期感知的,且在这个空fragment中注入了RequestManger实例对象。我们接下来,完整的看一下,这个特定的fragment内部的实现。查看SupportRequestManagerFragment的源码如下:
/**一个无view的fragment用于安全的持有requestManager用于开始、停止和管理glide的请求
*这个fragment作为子组件被添加到Activity或是Fragment上*/
public class SupportRequestManagerFragment extends Fragment
//Glide包自带的lifecycle组件(和androidx中相关lifecycle组件区分开)
private final ActivityFragmentLifecycle lifecycle;
....
@Nullable private RequestManager requestManager;
//new对象进行创建的时候,构建了一个lifecycle对象
public SupportRequestManagerFragment()
this(new ActivityFragmentLifecycle());
//成员变量lifecycle被赋值
public SupportRequestManagerFragment(@NonNull ActivityFragmentLifecycle lifecycle)
this.lifecycle = lifecycle;
//提供设置注入requestManger方法
public void setRequestManager(@Nullable RequestManager requestManager)
this.requestManager = requestManager;
//提供获取当前fragment的lifecycle
ActivityFragmentLifecycle getGlideLifecycle()
return lifecycle;
//获取requestManager方法
public RequestManager getRequestManager()
return requestManager;
......非生命周期相关代码省略....
//以下fragment本身生命周期方法的回调(这个不用多说,系统级别的api已经帮我们实现了这个回调)
@Override
public void onStart()
super.onStart();
//回调glide的生命周期组件lifecycle.onStart
lifecycle.onStart();
@Override
public void onStop()
super.onStop();
//回调glide的生命周期组件lifecycle.onStop
lifecycle.onStop();
@Override
public void onDestroy()
super.onDestroy();
lifecycle.onDestroy();
//回调glide的生命周期组件lifecycle.onDestroy
unregisterFragmentWithRoot();
.....
上述源码中的注释真的已经非常详细,我们也看到了和Glide生命周期最直接相关的类Lifecycle,实际上个接口,我们看一下究竟:
package com.bumptech.glide.manager;
import androidx.annotation.NonNull;
/** 一个监听接口,监听Activity和fragment的生命周期事件 */
public interface Lifecycle
void addListener(@NonNull LifecycleListener listener);
void removeListener(@NonNull LifecycleListener listener);
LifecycleListener,我们也看一下:
/**
* 真正的监听生命周期事件接口,有onStart、onStop、onDestroy
*/
public interface LifecycleListener
void onStart();
void onStop();
void onDestroy();
分析到这个位置,至少我们已经很清晰Glide的生命周期感知函数,并不想Activity、Fragment那样有那么多,就三个生命周期函数,分别是onStart、onStop、onDestroy。Glide的这三个生命周期正好的对应Activity、Fragment中的onStart、onStop、onDestory的调用来进行回调。具体怎么回调的,看代码层的实现,在上段SupportRequestManagerFragment的onStart方法中进行了lifecycle.onStart()的调用,lifecycle实例的实现例是ActivityFragmentLifecycle,查看源码:
class ActivityFragmentLifecycle implements Lifecycle
private final Set<LifecycleListener> lifecycleListeners =
Collections.newSetFromMap(new WeakHashMap<LifecycleListener, Boolean>());
...
@Override
public void addListener(@NonNull LifecycleListener listener)
....
@Override
public void removeListener(@NonNull LifecycleListener listener)
....
// lifecycle.onStart()方法的调用在这
void onStart()
isStarted = true;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) //回调了Glide中lifecycleListener的onStart
lifecycleListener.onStart();
....onStop、onDestory...
接下来我们是需要这里的lifecycle是谁,glide生命周期的监听过程我们就搞清楚了。还记得,我们前端代码在创建空Fragment的时候的这段代码吗?
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
通过工厂创建requestManger的时候,我们传入了当前这个空fragment穿件的glide的生命周期对象,addLifecycleListener就是在工厂方法最后调用的requestManger中去实现的。查看源码RequestManager的构造函数:
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())
Util.postOnUiThread(addSelfToLifecycle);
else
//主线程调用(和前面的分析也是一致的)
lifecycle.addListener(this);
lifecycle.addListener(connectivityMonitor);
defaultRequestListeners =
new CopyOnWriteArrayList<>(glide.getGlideContext().getDefaultRequestListeners());
setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());
glide.registerRequestManager(this);
lifecycle是空fragment中创建的lifecycle,addListener(this)中this就是requestManger,很显然requestManger实现了lifecycleListener的接口。
到此,小结一下:
第一步:我们添加的空Fragment中的生命周期方法(如onStart)执行,回调内部创建的ActivityFragmentLifecycle的生命周期方法(如onStart),
第二步:再在ActivityFragmentLifecylce中回调监听器的生命周期方法(如onStart),而监听器本质上就是RequestManger,实际上回调的就是requestManger的生命周期方法。
第三步:requestManger中的生命周期方法被调用,执行生命周期方法内的所需操作。
简单看一下,第三步中如果是onStop方法被调用,会干啥:
public synchronized void onStop()
//停止请求
pauseRequests();
targetTracker.onStop();
public synchronized void pauseRequests()
//交给requestTracker停止请求
requestTracker.pauseRequests();
public class RequestTracker
public void pauseRequests()
isPaused = true;
for (Request request : Util.getSnapshot(requests))
if (request.isRunning())
//请求停止
request.pause();
//添加到等待队列
pendingRequests.add(request);
三、总结
Glide的生命周期方法有三个onStart、onStop、onDestory。
Glide框架设计了lifecycle接口,用于添加生命周期的监听器ifecycleListener。
Glide在调用with方法的时候,去创建一个空Fragment,空Fragment中创建了ActivityFragmentLifecycle生命周期实例。
Glide在调用with方法中,去创建Glide、创建requestManger和Glide绑定,requestManger创建时传入空Fragment的生命周期对象ActivityFragmentLifecycle,并将自身做未监听器添加其中。
通过上述流程,Activity、Fragment的原生生命周期方法调用的时候,进行lifecycle对象调用,最终会调到requestManger的监听方法中,包括onStart、onStop、onDestroy。
RequestManger的生命周期监听方法调用,触发requestTracker对实际的request做出响应的处理。
流程并不是很复杂,这一章节,就省去流程图了。
以上是关于Glide 4.12 框架源码中的生命周期设计的主要内容,如果未能解决你的问题,请参考以下文章