glide生命周期管理、内存管理、缓存机制、加载器、观察者模式
前言:本系列博文主要通过借鉴其他优秀博文以及自己的实际开发经验综合得出,主要分析glide相关使用、机制以及设计模式等内容,相信这篇博文会让你对glide有更加深入的理解。本篇是系列文章的第二章。
篇二 glide的生命周期管理
前言:本篇博客将介绍glide的生命周期管理,如何与Fragment和Activity绑定的。 篇一
我们知道将 Activity/Fragment 对象作为参数传给Glide.with(context/fragment/activity)的好处是图片的加载会和 Activity/Fragment 的生命周期保持一致。下面我们来了解如何进行绑定的?
一、with()参数的类型:
Glide.with(argument)可以接收 Activity
、FragmentActivity
、Fragment
、v4.Fragment
、Context
、View
六种类型,这样就会创建一个看不见的fragment,Glide的生命周期就随着该Fragment的变化而变化。然后通过 RequestManagerRetriever 获取 RequestManager。
1-当参数是Fragment和View时:
这两种方法都是先确定其类型(使用instanceof),如果它的 Context 不属于 Activity、FragmentActivity、Fragment、v4.Fragment 则生命周期与应用同步,无需处理。即是:如果context不是Activity和Fragment,则生命周期与应用同步。
public static RequestManager with(@NonNull Context context) {
return getRetriever(context).get(context);
}
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());//找到view挂载的activity
if (activity == null) {// The view might be somewhere else, like a service.
return get(view.getContext().getApplicationContext());//获得应用的context
}
// 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对象,通过该对象创建Fragment并返回RequestManager对象
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对象,通过该对象创建Fragment并返回RequestManager对象
android.app.FragmentManager fm = activity.getFragmentManager();
return fragmentGet(activity, fm, null /*parentHint*/);
}
}
3-当参数是Fragment、v4.Fragment时:
@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);
}
}
可以看到这两种类型在调用 xxxfragmentGet()
时多传了一个 fragment。而 fragmentGet 与 supportFragmentGet 没有太大区别。
下面就从FragmentGet来进行分析:
FragmentGet()函数中有两个类是实现生命周期管理的核心 RequestManagerFragment 和 RequestManager。
private RequestManager fragmentGet(Context context, android.app.FragmentManager fm,
android.app.Fragment parentHint) {
//创建Fragemnt对象,通过该对象得到自己的RequestManager对象
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;
}
getRequestManagerFragment的实现:
private RequestManagerFragment getRequestManagerFragment(
@NonNull final android.app.FragmentManager fm,
@Nullable android.app.Fragment parentHint,
boolean isParentVisible) {
//查找tag为FRAGMENT_TAG的fragment
RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
//从HashMap中取出fm
current = pendingRequestManagerFragments.get(fm);
if (current == null) {
//创建fragment对象
current = new RequestManagerFragment();
//当fragment嵌套fragment时才会使用,否则parentHint是null
current.setParentFragmentHint(parentHint);
if (isParentVisible) {
//开始执行请求
current.getGlideLifecycle().onStart();
}
//将fm添加到HashMap中,防止fragment的重复创建
pendingRequestManagerFragments.put(fm, current);
//添加fragment
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
//从HashMap集合从移除fm
handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
}
}
return current;
}
从fm中去查找tag为FRAGMENT_TAG的fragment是否存在,
如果不存在就从pendingRequestManagerFragments这个HashMap中去取,
如果没有就创建一个fragment,添加到pendingRequestManagerFragments
并且将该fragment绑定到activity,绑定成功后则从pendingRequestManagerFragments移除fragment。
这里的pendingRequestManagerFragments主要是防止fragment重复创建(Glide生命周期管理),
因为每个activity必须对应一个唯一的fragment。
RequestManager 与 RequestManagerFragment 的合作:
RequestManager实现了LifecycleListener接口,用于管理Glide请求,可以同步Activity、Fragment生命周期进行启动、停止、重启等操作。
RequestManagerFragment作为一个无视图的Fragment可以和当前的Activity或者Fragment进行绑定,这样在自己的生命周期就可以同步监听到他们的生命周期,通过ActivityFragmentLifecycle将RequestManager进行生命周期同步。
childRequestManagerFragments用于存放当前Activity下所有的RequestManagerFragment;RequestManagerTreeNode存储了此RequestManagerFragment的父元素所对应的一组Fragment,层层嵌套,保证了上层变动后下层可以及时更新。
RequestManager的实现:
public class RequestManager implements LifecycleListener,
ModelTypes<RequestBuilder<Drawable>> {
private final Runnable addSelfToLifecycle = new Runnable() {
@Override
public void run() {
lifecycle.addListener(RequestManager.this);
}
};
public RequestManager(@NonNull Glide glide,
@NonNull Lifecycle lifecycle,
@NonNullRequestManagerTreeNode treeNode,
@NonNull Context context) {
this(
glide,lifecycle,
treeNode,
new RequestTracker(),
glide.getConnectivityMonitorFactory(),
context);
}
// Our usage is safe here.
@SuppressWarnings("PMD.ConstructorCallsOverridableMethod")
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()) {
//当在子线程时通过Handler将当前对象注册到ActivityFragmentLifecycle
mainHandler.post(addSelfToLifecycle);
} else {
//将当前对象注册到ActivityFragmentLifecycle
lifecycle.addListener(this);
}
//网络变化监听
lifecycle.addListener(connectivityMonitor);
...
}
//开始加载
@Override
public synchronized void onStart() {
resumeRequests();
//如果有动画则开始动画
targetTracker.onStart();
}
//停止加载
@Override
public synchronized void onStop() {
pauseRequests();
//如果有动画则动画停止
targetTracker.onStop();
}
//销毁
@Override
public synchronized void onDestroy() {
//如果有动画则动画结束并销毁
targetTracker.onDestroy();
...
}
//开始请求数据
synchronized void track(@NonNull Target<?> target, @NonNull Request request) {
targetTracker.track(target);
requestTracker.runRequest(request);
}
...
}
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);
}
//每个RequestManager对应一个LifecycleListener
void onStart() {
isStarted = true;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onStart();
}
}
//每个RequestManager对应一个LifecycleListener
void onStop() {
isStarted = false;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onStop();
}
}
//每个RequestManager对应一个LifecycleListener
void onDestroy() {
isDestroyed = true;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onDestroy();
}
}
}
由于ActivityFragmentLifecycle
对象是在fragment中创建并且它的onStart、onStop、onDestory
方法与fragment一一对应,这样就将RequestManager
的生命周期就与fragment关联起来了,也就与当前activity关联起来。
总结
所以 Glide 管理生命周期的整体流程就是先创建一个无视图的 Fragment,并同时创建这个 Fragment 的 ActivityFragmentLifeCycle 对象,当这个 Framgent 的生命周期发生变化时会调用 ActivityFragmentLifeCycle 使其中的 RequestManager 做出对应处理,由 RequestTracker 具体实现。