/**
* Begin a load with Glide by passing in a context.
*
* @param context Any context, will not be retained.
* @see #with(android.app.Activity)
* @see #with(android.app.Fragment)
* @see #with(androidx.fragment.app.Fragment)
* @see #with(androidx.fragment.app.FragmentActivity)
*/
@NonNull
public static RequestManager with(@NonNull Context context) {
return getRetriever(context).get(context);
}
@NonNull
public static RequestManager with(@NonNull Activity activity) {
return getRetriever(activity).get(activity);
}
@NonNull
public static RequestManager with(@NonNull FragmentActivity activity) {
return getRetriever(activity).get(activity);
}
@NonNull
public static RequestManager with(@NonNull Fragment fragment) {
return getRetriever(fragment.getContext()).get(fragment);
}
@SuppressWarnings("deprecation")
@Deprecated
@NonNull
public static RequestManager with(@NonNull android.app.Fragment fragment) {
return getRetriever(fragment.getActivity()).get(fragment);
}
@NonNull
public static RequestManager with(@NonNull View view) {
return getRetriever(view.getContext()).get(view);
}
可以看到,with()方法的重载种类非常多,既可以传入Activity,也可以传入Fragment或者是Context。每一个with()方法重载的代码都非常简单,都是先调用getRetriever方法得到一个RequestManagerRetriever对象,然后再调用RequestManagerRetriever的实例get()方法,去获取RequestManager对象。
RequestManagerRetriever类中
@NonNull
public RequestManager get(@NonNull Context context) {
if (context == null) {
throw new IllegalArgumentException("You cannot start a load on a null Context");
}
== 如果不是Application 并且是在主线程的情况==
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
&& ((ContextWrapper) context).getBaseContext().getApplicationContext() != null) {
return get(((ContextWrapper) context).getBaseContext());
}
}
== Application 或者是在非主线程的情况 ==
return getApplicationManager(context);
}
@NonNull
public RequestManager get(@NonNull FragmentActivity activity) {
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
FragmentManager fm = activity.getSupportFragmentManager();
return supportFragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
}
}
@NonNull
public RequestManager get(@NonNull Fragment fragment) {
Preconditions.checkNotNull(
fragment.getContext(),
"You cannot start a load on a fragment before it is attached or after it is destroyed");
if (Util.isOnBackgroundThread()) {
return get(fragment.getContext().getApplicationContext());
} else {
FragmentManager fm = fragment.getChildFragmentManager();
return supportFragmentGet(fragment.getContext(), fm, fragment, fragment.isVisible());
}
}
@SuppressWarnings("deprecation")
@Deprecated
@NonNull
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
public RequestManager get(@NonNull 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, fragment, fragment.isVisible());
}
}
@SuppressWarnings("deprecation")
@NonNull
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));
}
}
@SuppressWarnings("deprecation")
@NonNull
public RequestManager get(@NonNull View view) {
if (Util.isOnBackgroundThread()) {
return get(view.getContext().getApplicationContext());
}
Preconditions.checkNotNull(view);
Preconditions.checkNotNull(
view.getContext(), "Unable to obtain a request manager for a view without a Context");
Activity activity = findActivity(view.getContext());
// The view might be somewhere else, like a service.
if (activity == null) {
return get(view.getContext().getApplicationContext());
}
if (activity instanceof FragmentActivity) {
Fragment fragment = findSupportFragment(view, (FragmentActivity) activity);
return fragment != null ? get(fragment) : get((FragmentActivity) activity);
}
android.app.Fragment fragment = findFragment(view, activity);
if (fragment == null) {
return get(activity);
}
return get(fragment);
}
上述代码虽然看上去逻辑有点复杂,但是将它们梳理清楚后还是很简单的。RequestManagerRetriever类中看似有很多个get()方法的重载,什么Context参数,Activity参数,Fragment参数等等,实际上只有两种情况而已,即传入Application类型的参数,和传入非Application类型的参数。
如果我们是在非主线程当中使用的Glide,那么不管你是传入的Activity还是Fragment,都会被强制当成Application来处理。
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
}
我们先来看传入Application参数的情况。如果在Glide.with()方法中传入的是一个Application对象,那么这里就会调用带有Context参数的get()方法重载,然后会调用getApplicationManager()方法来获取一个RequestManager对象。其实这是最简单的一种情况,因为Application对象的生命周期即应用程序的生命周期,因此Glide并不需要做什么特殊的处理,它自动就是和应用程序的生命周期是同步的,如果应用程序关闭的话,Glide的加载也会同时终止。
接下来我们看传入非Application参数的情况。不管你在Glide.with()方法中传入的是Activity、FragmentActivity、v4包下的Fragment、还是app包下的Fragment,最终的流程都是一样的,那就是会向当前的Activity当中添加一个隐藏的Fragment。
那么这里为什么要添加一个隐藏的Fragment呢?因为Glide需要知道加载的生命周期。很简单的一个道理,如果你在某个Activity上正在加载着一张图片,结果图片还没加载出来,Activity就被用户关掉了,那么图片还应该继续加载吗?当然不应该。可是Glide并没有办法知道Activity的生命周期,于是Glide就使用了添加隐藏Fragment的这种小技巧,因为Fragment的生命周期和Activity是同步的,如果Activity被销毁了,Fragment是可以监听到的,这样Glide就可以捕获这个事件并停止图片加载了
分别对应的v4包和APP包下的两种Fragment的情况。
supportFragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity))
fragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity))
分析v4包下的,注释在代码中
@NonNull
public RequestManager get(@NonNull FragmentActivity activity) {
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else {
//这里是保证当前的FragmentActivity 或者是v4fragment attah 的FragmentActivity没有被销毁
assertNotDestroyed(activity);
FragmentManager fm = activity.getSupportFragmentManager();
// 创建一个无ui的fragment
return supportFragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
}
}
supportFragmentGet方法中创建fragment的方法
SupportRequestManagerFragment current =
getSupportRequestManagerFragment(fm, parentHint, isParentVisible);
== 这里的创建逻辑 首先通过tag来寻找是否创建过该fragment,如果没有的话,在
Map<FragmentManager,SupportRequestManagerFragment>pendingSupportRequestManagerFragments
中查询是否保存过,如果没有的话则创建一个无ui的fragment,并且保存到map中,并且如果acticity是
visible状态,则注册current.getGlideLifecycle().onStart(),然后在通过handler发送消息,将map
中的该fragment删除
@NonNull
private SupportRequestManagerFragment getSupportRequestManagerFragment(
@NonNull final FragmentManager fm, @Nullable Fragment parentHint, boolean isParentVisible) {
SupportRequestManagerFragment current =
(SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
current = pendingSupportRequestManagerFragments.get(fm);
if (current == null) {
current = new SupportRequestManagerFragment();
current.setParentFragmentHint(parentHint);
if (isParentVisible) {
current.getGlideLifecycle().onStart();
}
pendingSupportRequestManagerFragments.put(fm, current);
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
}
}
return current;
}
我们发现在创建fragment的时候会在构造方法中创建ActivityFragmentLifecycle 对象
public class SupportRequestManagerFragment extends Fragment {
private final ActivityFragmentLifecycle lifecycle;
public SupportRequestManagerFragment() {
this(new ActivityFragmentLifecycle());
}
@VisibleForTesting
@SuppressLint("ValidFragment")
public SupportRequestManagerFragment(@NonNull ActivityFragmentLifecycle lifecycle) {
this.lifecycle = lifecycle;
}
@NonNull
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();
}
}
ActivityFragmentLifecycle类是生命周期回调的管理类,它实现了LifeCycle接口,会将LifecycleListener
的接口加入到ActivityFragmentLifecycle类中的Set集合中,当SupportRequestManagerFragment的生命
周期的方法触发时,会调用ActivityFragmentLifeCycle的相应方法。主要保存了isStarted和isDestroyed变
量,并提供了addListener和removeListener方法,如果想获取到生命周期的回调,
只需调用addListener()方法注册即可。
class ActivityFragmentLifecycle implements Lifecycle {
private final Set<LifecycleListener> lifecycleListeners =
Collections.newSetFromMap(new WeakHashMap<LifecycleListener, Boolean>());
private boolean isStarted;
private boolean isDestroyed;
@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() {
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();
}
}
}