Glide源码学习之生命周期监听
使用Glide时,第一步是使用Glide.with()函数,通过下面的源码可以发现,with重载了多个不同类型的参数,之所以重载这么多,是为了针对不同的生命周期做不同的处理。
Glide
public class Glide implements ComponentCallbacks2 {
@NonNull
private static RequestManagerRetriever getRetriever(@Nullable Context context){
return Glide.get(context).getRequestManagerRetriever();
}
@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);
}
@NonNull
public RequestManagerRetriever getRequestManagerRetriever() {
return requestManagerRetriever;
}
}
Glide 中with方法参数重载,可接收多种参数类型,均返回RequestManager对象,而RequestManager对象是通过RequestManagerRetriever的with方法生成的。
RequestManagerRetriever
public class RequestManagerRetriever implements Handler.Callback {
@NonNull
private RequestManager getApplicationManager(@NonNull Context context) {
if (applicationManager == null) {
synchronized (this) {
if (applicationManager == null) {
Glide glide = Glide.get(context.getApplicationContext());
applicationManager =
factory.build(
glide,
new ApplicationLifecycle(),
new EmptyRequestManagerTreeNode(),
context.getApplicationContext());
}
}
}
return applicationManager;
}
@NonNull
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
&& ((ContextWrapper) context).getBaseContext().getApplicationContext() != null) {
return get(((ContextWrapper) context).getBaseContext());
}
}
return getApplicationManager(context);
}
@NonNull
public RequestManager get(@NonNull FragmentActivity activity) {
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
frameWaiter.registerSelf(activity);
FragmentManager fm = activity.getSupportFragmentManager();
return supportFragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
}
}
@NonNull
public RequestManager get(@NonNull Fragment fragment) {
if (Util.isOnBackgroundThread()) {
return get(fragment.getContext().getApplicationContext());
} else {
if (fragment.getActivity() != null) {
frameWaiter.registerSelf(fragment.getActivity());
}
FragmentManager fm = fragment.getChildFragmentManager();
return supportFragmentGet(fragment.getContext(), fm, fragment, fragment.isVisible());
}
}
@SuppressWarnings("deprecation")
@NonNull
public RequestManager get(@NonNull Activity activity) {
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else if (activity instanceof FragmentActivity) {
return get((FragmentActivity) activity);
} else {
assertNotDestroyed(activity);
frameWaiter.registerSelf(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());
}
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);
}
// Standard Fragments.
android.app.Fragment fragment = findFragment(view, activity);
if (fragment == null) {
return get(activity);
}
return get(fragment);
}
@NonNull
private RequestManager supportFragmentGet(
@NonNull Context context,
@NonNull FragmentManager fm,
@Nullable Fragment parentHint,
boolean isParentVisible) {
SupportRequestManagerFragment current = getSupportRequestManagerFragment(fm, parentHint);
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
Glide glide = Glide.get(context);
requestManager =
factory.build(glide, current.getGlideLifecycle(),current.getRequestManagerTreeNode(), context);
if (isParentVisible) {
requestManager.onStart();
}
current.setRequestManager(requestManager);
}
return requestManager;
}
//重要,避免Fragment在一个作用域中重复创建,所以会发送一个post消息,同时也保存在一个本地的map中
@NonNull
private SupportRequestManagerFragment getSupportRequestManagerFragment(
@NonNull final FragmentManager fm, @Nullable Fragment parentHint) {
//尝试从临时记录中获取一个Fragment对象
SupportRequestManagerFragment current = pendingSupportRequestManagerFragments.get(fm);
if (current == null) {
//查找tag为FRAGMENT_TAG的Fragment
current = (SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
//如果Fragment不存在,创建一个新的
current = new SupportRequestManagerFragment();
current.setParentFragmentHint(parentHint);
//更新临时记录
pendingSupportRequestManagerFragments.put(fm, current);
//提交Fragment事务
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
//post一个消息
handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
}
}
return current;
}
public interface RequestManagerFactory {
@NonNull
RequestManager build(
@NonNull Glide glide,
@NonNull Lifecycle lifecycle,
@NonNull RequestManagerTreeNode requestManagerTreeNode,
@NonNull Context context);
}
}
对应Glide中重载的多个with方法,该类中在获取RequestManager方法中也重载了多个get方法。
在该类中,会创建用于监听生命周期的空白的Fragment方法,并完成其与RequestManager的绑定关系。
在监听生命周期方面,分为了两大类,一类是和应用的生命周期绑定的,一类是需要创建空白的生命周期,即和该Fragment的生命周期绑定的。
SupportRequestManagerFragment
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;
}
@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();
}
}
用于监听页面生命周期的空白的Fragment,持有ActivityFragmentLifecycle对象,在生命周期变化,即onStart、onStop、onDestroy执行的时候,会将生命周期变化同步到ActivityFragmentLifecycle中。
ActivityFragmentLifecycle
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();
}
}
}
借助SupportRequestManagerFragment监听页面的生命周期,在SupportRequestManagerFragment中持有其对象,在Fragment生命周期函数执行时,会同步到该类中。
该类中保存有观察者对象,即实现了LifecycleListener接口的对象,当Fragment生命周期的变化通知到SupportRequestManagerFragment后,会遍历这些实现了LifecycleListener接口的对象,然后通知生命周期的变化。
Lifecycle
public interface Lifecycle {
void addListener(@NonNull LifecycleListener listener);
void removeListener(@NonNull LifecycleListener listener);
}
定了添加和移除观察者的方法。
LifecycleListener
class ApplicationLifecycle implements Lifecycle {
@Override
public void addListener(@NonNull LifecycleListener listener) {
listener.onStart();
}
@Override
public void removeListener(@NonNull LifecycleListener listener) {
// Do nothing.
}
}
\