在Android开发中,或多或少你都会使用过很多的框架,但是没有一个框架会像Glide
一样好用。Glide.with(context).load(url).into(imageView).
一行代码解决了很多问题,今天我们就来深入Glide的源码,来看看这一行代码背后的故事。先从Glide的with()方法开始我们的探索。
with()过程分析
Glide类里面的with()方法
public static RequestManager with(Context context) {
RequestManagerRetriever retriever = RequestManagerRetriever.get();
return retriever.get(context);
}
public static RequestManager with(Activity activity) {
RequestManagerRetriever retriever = RequestManagerRetriever.get();
return retriever.get(activity);
}
public static RequestManager with(FragmentActivity activity) {
RequestManagerRetriever retriever = RequestManagerRetriever.get();
return retriever.get(activity);
}
public static RequestManager with(android.app.Fragment fragment) {
RequestManagerRetriever retriever = RequestManagerRetriever.get();
return retriever.get(fragment);
}
/**
* Begin a load with Glide that will be tied to the given {@link android.support.v4.app.Fragment}'s lifecycle and
* that uses the given {@link android.support.v4.app.Fragment}'s default options.
*
* @param fragment The fragment to use.
* @return A RequestManager for the given Fragment that can be used to start a load.
*/
public static RequestManager with(Fragment fragment) {
RequestManagerRetriever retriever = RequestManagerRetriever.get();
return retriever.get(fragment);
}
Glide类里面有很多with()方法的重载,在with()方法中传入不同类型的参数,来调用不同的重载的with()方法。可以看到,Glide为
Activity和Fragment(android.app.Fragment和v4包下的Fragment)都提供Glide的使用。
通过看Glide的这几个with()方法,可以发现里面都调用了RequestManageRetriever
类的get()
方法。
- RequestManagerRetriever类:帮助拿到RequestManager对象,
RequestManageRetriever类里面的get()方法
private static final RequestManagerRetriever INSTANCE = new RequestManagerRetriever();
public static RequestManagerRetriever get() {
return INSTANCE;
}
这个RequestManagerRetriever类里面的get()方法是一个static的静态内部方法,返回一个静态RequestManagerRetriever对象,这是一个单例实现。
在Glide类的这几个重载的with()方法中,首先都是先得到了RequestManagerRetriever对象,紧接着都调用了RequestManagerRetriever对象的带参数的实例get()
方法,只不过不同的with()方法中传入RequestManagerRetriever类的get()方法的参数类型不同罢了。
RequestManagerRetriever类中
private RequestManager getApplicationManager(Context context) {
// Either an application context or we're on a background thread.
if (applicationManager == null) {
synchronized (this) {
if (applicationManager == null) {
// Normally pause/resume is taken care of by the fragment we add to the fragment or activity.
// However, in this case since the manager attached to the application will not receive lifecycle
// events, we must force the manager to start resumed using ApplicationLifecycle.
applicationManager = new RequestManager(context.getApplicationContext(),
new ApplicationLifecycle(), new EmptyRequestManagerTreeNode());
}
}
}
return applicationManager;
}
public RequestManager get(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);
}
public RequestManager get(FragmentActivity activity) {
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
FragmentManager fm = activity.getSupportFragmentManager();
return supportFragmentGet(activity, fm);
}
}
public RequestManager get(Fragment fragment) {
if (fragment.getActivity() == null) {
throw new IllegalArgumentException("You cannot start a load on a fragment before it is attached");
}
if (Util.isOnBackgroundThread()) {
return get(fragment.getActivity().getApplicationContext());
} else {
FragmentManager fm = fragment.getChildFragmentManager();
return supportFragmentGet(fragment.getActivity(), fm);
}
}
public RequestManager get(Activity activity) {
if (Util.isOnBackgroundThread() || Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
return get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
android.app.FragmentManager fm = activity.getFragmentManager();
return fragmentGet(activity, fm);
}
}
public RequestManager get(android.app.Fragment fragment) {
if (fragment.getActivity() == null) {
throw new IllegalArgumentException("You cannot start a load on a fragment before it is attached");
}
if (Util.isOnBackgroundThread() || Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
return get(fragment.getActivity().getApplicationContext());
} else {
android.app.FragmentManager fm = fragment.getChildFragmentManager();
return fragmentGet(fragment.getActivity(), fm);
}
}
可以看到在RequestManagerRetriever类中,有很多get()实例方法的重载,归根结底的分为传入Application类型的和非Application类型的参数。
传入Application类型的参数时,就会调用getApplicationManager()
方法。在这个方法中会生成RequestManager对象并返回,这个RequestManager对象就是Glide类的with()方法中所返回的。
传入非Application类型的参数时,会根据传入的是Activity,还是Fragment(android.app.Fragment和v4包下的Fragment)来调用不同的get()方法。这些get()方法中传入的参数类型不一样,但是这些get()方法中的大致处理流程是一致的。我们选一个传入v4包下的Fragment类型的get()方法来看。
传入v4包下的Fragment到RequestManagerRetriever的实例get()方法
static final String FRAGMENT_TAG = "com.bumptech.glide.manager";
final Map<android.app.FragmentManager, RequestManagerFragment> pendingRequestManagerFragments =
new HashMap<android.app.FragmentManager, RequestManagerFragment>();
private final Handler handler;
public RequestManager get(Fragment fragment) {
if (fragment.getActivity() == null) {
throw new IllegalArgumentException("You cannot start a load on a fragment before it is attached");
}
//不在主线程中
if (Util.isOnBackgroundThread()) {
//调用Application类型参数的get()方法
return get(fragment.getActivity().getApplicationContext());
} else {
//管理Fragment的FragmentManager
FragmentManager fm = fragment.getChildFragmentManager();
return supportFragmentGet(fragment.getActivity(), fm);
}
}
RequestManager supportFragmentGet(Context context, FragmentManager fm) {
// SupportRequestManagerFragment是一个无UI的Fragment
SupportRequestManagerFragment current = getSupportRequestManagerFragment(fm);
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
requestManager = new RequestManager(context, current.getLifecycle(), current.getRequestManagerTreeNode());
current.setRequestManager(requestManager);
}
return requestManager;
}
SupportRequestManagerFragment getSupportRequestManagerFragment(final FragmentManager fm) {
SupportRequestManagerFragment current = (SupportRequestManagerFragment) fm.findFragmentByTag(
FRAGMENT_TAG);
if (current == null) {
current = pendingSupportRequestManagerFragments.get(fm);
if (current == null) {
current = new SupportRequestManagerFragment();
pendingSupportRequestManagerFragments.put(fm, current);
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
}
}
return current;
}
public boolean handleMessage(Message message) {
boolean handled = true;
Object removed = null;
Object key = null;
switch (message.what) {
case ID_REMOVE_FRAGMENT_MANAGER:
android.app.FragmentManager fm = (android.app.FragmentManager) message.obj;
key = fm;
removed = pendingRequestManagerFragments.remove(fm);
break;
case ID_REMOVE_SUPPORT_FRAGMENT_MANAGER:
FragmentManager supportFm = (FragmentManager) message.obj;
key = supportFm;
removed = pendingSupportRequestManagerFragments.remove(supportFm);
break;
default:
handled = false;
}
if (handled && removed == null && Log.isLoggable(TAG, Log.WARN)) {
Log.w(TAG, "Failed to remove expected request manager fragment, manager: " + key);
}
return handled;
}
- SupportRequestManagerFragment:是一个无UI的虚拟的Fragment,它是来辅助Glide来进行生命周期管理的。因为当使用Glide加载图片时,Glide不会感知到Activity的销毁。通过这个虚拟的Fragment来感知到Activity的生命周期,并作出及时的反应。
- RequestManagerFragment与SupportRequestManagerFragment一样,都是虚拟的Fragment,只不过前者是android.app.Fragment包下的Fragment,后者是v4包下的Fragment。
分析一下这个过程,在RequestManagerRetriever类的get(Fragment fragment)
方法中,先是进行判断,不在主线程中就会调用调用Application类型参数的get()
方法,否则生成一个管理Fragment的FragmentManager,然后调用supportFragmentGet()
并将生成的FragmentManager对象传入。
在supportFragmentGet()
方法中,先是调用了getSupportRequestManagerFragment()
方法;那先进入这个方法中,在这个方法中,先是通过fm.findFragmentByTag( FRAGMENT_TAG)
来寻找是否已经存在这个SupportRequestManagerFragment,如果存在就直接返回。否则生成SupportRequestManagerFragment对象,并以FragmentManager为key,SupportRequestManagerFragment对象为value存入pendingRequestManagerFragments中,这个pendingRequestManagerFragments是一个HashMap。接着将刚刚生成的Fragment加入事物管理器中,但是紧接着又调用handel
发送了一条消息,我们进入handleMessage()
方法中,可以发现它将刚刚加入HashMap的Fragment又删除了。
怎么回事?刚刚加入进去,怎么紧接着又给删除了。
来分析一下这个过程。
首先在Fragment和Activity绑定时,是通过开启事务的方式来进行绑定的,也就是通过Hander来处理的。(感兴趣这个过程的话可以通过看源码来发现)
Glide.with(context).load(url).into(image1);
Glide.with(context).load(url).into(image2);
我们看上面的两行代码,在同一个Activity中分别为两个ImageView加载图片。
当第一行代码运行到getSupportRequestManagerFragment()
方法时,由于之前没有SupportRequestManagerFragment实例,这个时候会生成一个新的SupportRequestManagerFragment实例,并保存在HashMap中,生成新的SupportRequestManagerFragment实例时,就会发Fragment于Activity的绑定,Handler会发送消息来进行绑定,假设这个消息为m1,紧接着在getSupportRequestManagerFragment()
方法中,就会使用Handler来发送从HashMap中删除保存的SupportRequestManagerFragment实例对象的消息,假设这个消息为m2。
在Handler处理消息时,如果在m1与m2消息之前,Handler的消息队列中还存在其他的消息,此时m1与m2还没有得到处理,就是此时还没有进行Fragment与Activity的绑定。第二行Glide.with(context).load(url).into(image2);
代码已经进行到了getSupportRequestManagerFragment()
方法了,如果此时我们不将Fragment存入HashMap中,就会重新生成一个SupportRequestManagerFragment
,这是Glide所不允许的,每一个Activity或者Fragment在使用Glide时,只能有一个所依附的虚拟的Fragment。所以将之前所生成的SupportRequestManagerFragment
存储到HashMap中,这样就不会重复生成SupportRequestManagerFragment
,等到SupportRequestManagerFragment
与Activity绑定完成后,也就是消息m1处理完成后,再将SupportRequestManagerFragment
从HashMap中销毁。
这个过程分析完了,之后在getSupportRequestManagerFragment()
方法中将Fragment返回,接着回到supportFragmentGet()
方法中。在这个方法中,接着就生成了RequestManager
对象。注意到,在生成这个RequestManager
对象时构造器中传入的是刚刚从getSupportRequestManagerFragment()
方法中返回的SupportRequestManagerFragment
对象中的一些东西。
Glide的with()过程分析完了,最终得到了Gilde类的with()方法中需要的RequsetManager对象。
Glide的生命周期
从SupportRequestManagerFragment
类开始吧。
来看一下SupportRequestManagerFragment
类。
SupportRequestManagerFragment类
private final ActivityFragmentLifecycle lifecycle;
//在SupportRequestManagerFragment类的构造方法中生成ActivityFragmentLifecycle对象
public SupportRequestManagerFragment() {
this(new ActivityFragmentLifecycle());
}
public SupportRequestManagerFragment(ActivityFragmentLifecycle lifecycle) {
this.lifecycle = lifecycle;
}
- ActivityFragmentLifecycle类是生命周期回调的管理类,它实现了LifeCycle接口,会将LifecycleListener的接口加入到ActivityFragmentLifecycle类中的Set集合中,当SupportRequestManagerFragment的生命周期的方法触发时,会调用ActivityFragmentLifeCycle的相应方法。
ActivityFragmentLifeCycle的相应方法
private final Set<LifecycleListener> lifecycleListeners =
Collections.newSetFromMap(new WeakHashMap<LifecycleListener, Boolean>());
private boolean isStarted;
private boolean isDestroyed;
@Override
public void addListener(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();
}
}
SupportRequestManagerFragment类中
@Override
public void onStart() {
super.onStart();
lifecycle.onStart();
}
@Override
public void onStop() {
super.onStop();
lifecycle.onStop();
}
@Override
public void onDestroy() {
super.onDestroy();
lifecycle.onDestroy();
}
可以看到当SupportRequestManagerFragment类中的相应的生命周期的方法调用时就会调用ActivityFragmentLifeCycle的相应方法。
继续SupportRequestManagerFragment类。
SupportRequestManagerFragment类中
private final RequestManagerTreeNode requestManagerTreeNode =
new SupportFragmentRequestManagerTreeNode();
private final HashSet<SupportRequestManagerFragment> childRequestManagerFragments =
new HashSet<SupportRequestManagerFragment>();
private SupportRequestManagerFragment rootRequestManagerFragment;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
rootRequestManagerFragment = RequestManagerRetriever.get()
.getSupportRequestManagerFragment(getActivity().getSupportFragmentManager());
if (rootRequestManagerFragment != this) {
rootRequestManagerFragment.addChildRequestManagerFragment(this);
}
}
@Override
public void onDetach() {
super.onDetach();
if (rootRequestManagerFragment != null) {
rootRequestManagerFragment.removeChildRequestManagerFragment(this);
rootRequestManagerFragment = null;
}
}
private void addChildRequestManagerFragment(SupportRequestManagerFragment child) {
childRequestManagerFragments.add(child);
}
private void removeChildRequestManagerFragment(SupportRequestManagerFragment child) {
childRequestManagerFragments.remove(child);
}
public Set<SupportRequestManagerFragment> getDescendantRequestManagerFragments() {
if (rootRequestManagerFragment == null) {
return Collections.emptySet();
} else if (rootRequestManagerFragment == this) {
return Collections.unmodifiableSet(childRequestManagerFragments);
} else {
HashSet<SupportRequestManagerFragment> descendants =
new HashSet<SupportRequestManagerFragment>();
for (SupportRequestManagerFragment fragment
: rootRequestManagerFragment.getDescendantRequestManagerFragments()) {
if (isDescendant(fragment.getParentFragment())) {
descendants.add(fragment);
}
}
return Collections.unmodifiableSet(descendants);
}
}
private boolean isDescendant(Fragment fragment) {
Fragment root = this.getParentFragment();
while (fragment.getParentFragment() != null) {
if (fragment.getParentFragment() == root) {
return true;
}
fragment = fragment.getParentFragment();
}
return false;
}
private class SupportFragmentRequestManagerTreeNode implements RequestManagerTreeNode {
@Override
public Set<RequestManager> getDescendants() {
Set<SupportRequestManagerFragment> descendantFragments = getDescendantRequestManagerFragments();
HashSet<RequestManager> descendants = new HashSet<RequestManager>(descendantFragments.size());
for (SupportRequestManagerFragment fragment : descendantFragments) {
if (fragment.getRequestManager() != null) {
descendants.add(fragment.getRequestManager());
}
}
return descendants;
}
}
在SupportRequestManagerFragment刚刚和Activity建立连接的时候即在onAttach()方法中,会初始化rootRequestManagerFragment
实例变量。
rootRequestManagerFragment = RequestManagerRetriever.get()
.getSupportRequestManagerFragment(getActivity().getSupportFragmentManager());
注意这个初始化的过程,在getSupportRequestManagerFragment()
方法中传入的是getActivity().getSupportFragmentManager()
。
- 如果在Glide.with()时传入的是Activity类型的参数,则会得到Activity的SupportRequestManagerFragment也就是自己。如果在Glide.with()时传入的是Fragment类型的参数,则rootRequestManagerFragment指向的是该Fragment所依赖的Activity的SupportRequestManagerFragment。如果Fragment所依赖的SupportRequestManagerFragment存在则直接调用,否则为该Fragment所依赖的Activity创建SupportRequestManagerFragment。
- rootRequestManagerFragment指向根Activity的SupportRequestManagerFragment。
在onAttach()方法中,如果rootRequestManagerFragment不是本身,即rootRequestManagerFragment指向根Activity,则将本身保存到childRequestManagerFragments
集合中。也就是在这个集合中保存了Activity的所有的子Fragment的SupportRequestManagerFragment。
当Fragment销毁时,在这个Fragment中的子Fragment会怎么样?当然也是会销毁啊。也就是父Fragment的生命周期的方法被调用时,子Fragment的生命周期的方法也要会被调用。
- RequestManagerTreeNode接口:这个接口用来保存请求树节点,SupportFragmentRequestManagerTreeNode类继承于这个接口.
public interface RequestManagerTreeNode {
/**
* Returns all descendant {@link RequestManager}s relative to the context of the current {@link RequestManager}.
*/
Set<RequestManager> getDescendants();
}
看一下SupportFragmentRequestManagerTreeNode类
,这个类只有一个getDescendants()方法,先是利用getDescendantRequestManagerFragments()
方法得到一个SupportRequestManagerFragment的集合。
一个例子,一个Activity有两个Fragment,分别为F1和F2,Activity有一个SRMF(SupportRequestManagerFragment),F1和F2分别有一个SRFM,F1和F2分别又有两个Fragment,分别为F11,F12,F21,F22,这4个Fragment分别拥有SRMF。所以一共有6个SRMF保存在上面所说的rootRequestManagerFragment
所指向的集合中。所以当F1生命周期要做出反应时,它的子Fragment分别为F11和F12对应的SRMF也要有相应的反应。但F2的子Fragment的SRMF不做出反应。那怎么得到F1的子Fragment的SRMF,这就是SupportFragmentRequestManagerTreeNode类
的作用了。
接着看。
在getDescendantRequestManagerFragments()
方法中,如果自己不是rootRequestManagerFragment
就会在for()循环中遍历返回的rootRequestManagerFragment
所指向的集合,这个集合中保存了根Activity的所有的子Fragment的SRMF。接着每遍历一次,就会调用isDescendant()
方法进行判断,比如说这个本身的SupportRequestManagerFragment是F1,所有每次都会遍历返回的集合的SPMF是不是F1的子Fragment的SRMF。如果是的话,就将这个SRMF加入集合。
最后在SupportFragmentRequestManagerTreeNode类
的getDescendants()
方法中得到的都是Fragment的子Fragment的SRMF,最后将子Fragment的SRMF中的RequestManager对象的集合返回。
所以SupportFragmentRequestManagerTreeNode类
的getDescendants()
方法返回的是Fragment的子Fragment的SRMF的RequestManager对象的集合。
接着来看RequestManager类
。
RequestManager类
实现了LifecycleListener
接口。可以启动,停止,管理Glide的Request请求,是实现Glide加载资源的管理类,是Glide生命周期实现的关键类 。
RequestManager类
private final Context context;
private final Lifecycle lifecycle;
private final RequestManagerTreeNode treeNode;
private final RequestTracker requestTracker;
public RequestManager(Context context, Lifecycle lifecycle, RequestManagerTreeNode treeNode) {
this(context, lifecycle, treeNode, new RequestTracker(), new ConnectivityMonitorFactory());
}
RequestManager(Context context, final Lifecycle lifecycle, RequestManagerTreeNode treeNode,
RequestTracker requestTracker, ConnectivityMonitorFactory factory) {
this.context = context.getApplicationContext();
this.lifecycle = lifecycle;
this.treeNode = treeNode;
this.requestTracker = requestTracker;
......
if (Util.isOnBackgroundThread()) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
lifecycle.addListener(RequestManager.this);
}
});
} else {
lifecycle.addListener(this);
}
lifecycle.addListener(connectivityMonitor);
}
可以看见,在RequestManager的构造器中将RequestManager对象加入到ActivityLifeCycle中去。
再看看RequestManager类实现的LifeCycleListener接口的方法。
RequestManager类实现的LifeCycleListener接口的方法(onStop)
public boolean isPaused() {
Util.assertMainThread();
return requestTracker.isPaused();
}
public void pauseRequests() {
Util.assertMainThread();
requestTracker.pauseRequests();
}
@Override
public void onStop() {
pauseRequests();
}
可以看见在这些方法中真正起作用的是RequestTracker。
- RequestTracker类:所有请求的真正执行者
来捋一下思路,首先是Glide为了管理生命周期,创建了一个无UI的虚拟的Fragment,在这个Fragment创建的时候就生成了ActivityFragmentLifeCycle
生命周期的管理的对象,当Fragment的生命周期变化时就会调用ActivityFragmentLifeCycle
的相应的方法。而RequestManager
类实现了LifeCycleListener
接口,在RequestManager
的构造器中会将创建的RequestManager
对象加入到
ActivityFragmentLifeCycle
的管理LifeCycleListener
接口的集合中去,所以当ActivityFragmentLifeCycle
的相应的方法调用时就会调用RequestManager
对象的相应方法,而在RequestManager
对象的相应方法真正的执行者是RequestTracker
。
网友评论