Glide 中运用到的优秀技术有很多值得我们深入学习,这篇文章就来介绍一下 Glide 的生命周期是如何与 Activity、Fragment 进行绑定的。
一、with()入参分类
Glide.with(arg)可以接收 Activity
、FragmentActivity
、Fragment
、v4.Fragment
、Context
、View
六种类型,然后通过 RequestManagerRetriever 获取 RequestManager。
1.Context、View
这两种方法都是先确定其类型,如果它的 Context 不属于 Activity、FragmentActivity、Fragment、v4.Fragment 则生命周期与应用同步,无需处理。
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(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());
}
// Support Fragments.
// Although the user might have non-support Fragments attached to FragmentActivity, searching
// for non-support Fragments is so expensive pre O and that should be rare enough that we
// prefer to just fall back to the Activity directly.
if (activity instanceof FragmentActivity) {
Fragment fragment = findSupportFragment(view, (FragmentActivity) activity);
return fragment != null ? get(fragment) : get(activity);
}
// Standard Fragments.
android.app.Fragment fragment = findFragment(view, activity);
if (fragment == null) {
return get(activity);
}
return get(fragment);
}
2.FragmentActivity、Activity
这两个只有 FragmentManager 不同,其他流程都相同。
public RequestManager get(FragmentActivity activity) {
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
// SupportFragmentManager
FragmentManager fm = activity.getSupportFragmentManager();
return supportFragmentGet(activity, fm, null /*parentHint*/);
}
}
public RequestManager get(Activity activity) {
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
// FragmentManager
android.app.FragmentManager fm = activity.getFragmentManager();
return fragmentGet(activity, fm, null /*parentHint*/);
}
}
3.Fragment、v4.Fragment
可以看到这两种类型在调用 ***fragmentGet()
时多传了一个 fragment。而 fragmentGet 与 supportFragmentGet 没有太大区别,
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
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();
// fragmentGet
return fragmentGet(fragment.getActivity(), fm, fragment);
}
}
public RequestManager get(Fragment fragment) {
Preconditions.checkNotNull(fragment.getActivity(),
"You cannot start a load on a fragment before it is attached or after it is destroyed");
if (Util.isOnBackgroundThread()) {
return get(fragment.getActivity().getApplicationContext());
} else {
FragmentManager fm = fragment.getChildFragmentManager();
// supportFragmentGet
return supportFragmentGet(fragment.getActivity(), fm, fragment);
}
}
二、fragmentGet() 与 supportFragmentGet()
fragmentGet()
与 supportFragmentGet()
两个函数原理其实相同,所以这里就 fragmentGet 来进行讲解。
这个函数中有两个类是实现生命周期管理的核心 RequestManagerFragment 和 RequestManager。
private RequestManager fragmentGet(Context context, android.app.FragmentManager fm,
android.app.Fragment parentHint) {
RequestManagerFragment current = getRequestManagerFragment(fm, parentHint);
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
Glide glide = Glide.get(context);
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
current.setRequestManager(requestManager);
}
return requestManager;
}
三、RequestManager 与 RequestManagerFragment 的合作
RequestManager
实现了 LifecycleListener 接口,用于管理 Glide 的请求,可以同步 Activity、Fragment 生命周期进行启动、停止、重启操作。
RequestManagerFragment
作为一个无视图的 Fragment 可以和当前的 Activity 或者 Fragment 进行绑定,这样在自己的生命周期就可以同步监听到它们的生命周期,通过 ActivityFragmentLifecycle 将 RequestManager 进行生命周期同步。
childRequestManagerFragments 用于存放当前 Activity 下所有的 RequestManagerFragment;RequestManagerTreeNode 存储了此 RequestManagerFragment 的父元素所对应的一组Fragment。这样层层嵌套,保证了上层变动后下层可以实时更新。
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
RequestManagerFragment getRequestManagerFragment(
final android.app.FragmentManager fm, android.app.Fragment parentHint) {
RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
current = pendingRequestManagerFragments.get(fm);
if (current == null) {
current = new RequestManagerFragment();
current.setParentFragmentHint(parentHint);
pendingRequestManagerFragments.put(fm, current);
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
}
}
return current;
}
getRequestManagerFragment 会从 FragmentManager 中查找当前 Activity 或者 Fragment 是否已经创建过标记为 FRAGMENT_TAG 的 RequestManagerFragment,如果没有找到会将其创建并添加到 FragmentManager 中。
可以看到新创建的 RequestManagerFragment 刚刚放入 pendingRequestManagerFragments,但是紧接着又调用 handler
将其移除了,这是为了防止同一个界面创建多个 RequestManagerFragment。
总结
所以 Glide 管理生命周期的整体流程就是先创建一个无视图的 Fragment,并同时创建这个 Fragment 的 ActivityFragmentLifeCycle 对象,当这个 Framgent 的生命周期发生变化时会调用 ActivityFragmentLifeCycle 使其中的 RequestManager 做出对应处理,由 RequestTracker 具体实现。
网友评论