一 概述
Glide 中一个重要的特性就是Request可以绑定Activity或者fragment的onStart而resume,onStop而pause,onDestroy而clear,所以Glide可以节约流量内存,防止内存泄露,但是要注意不要传入在with()方法里传入application,不然就没办法对生命周期进行管理了。
二 核心类
- RequestManager:实现了LifeCycleListener,主要作用是结合Activity或者Fragment的生命周期,对Request进行管理,其中关联的方法有pauseRequests(), resumeRequests(), clearRequests()。
- RequestManagerRetriever:获取RequestManager,和SupportRequestManagerFragment,并将二者绑定,从而在fragment的生命周期方法中可回调到RequestManager对request进行生命周期管理的相应方法。
- SupportRequestManagerFragment, 空白Fragment,与RequestManager进行了绑定,作用为提供Fragment生命周期管理方法入口,如onStart(), onStop(), onDestroy()。
- ActivityFragmentLifecycle, 管理LifecycleListener, 空白Fragment会回调它的onStart(), onStop(), onDestroy()
- LifecycleListener,接口,定义生命周期管理方法,onStart(), onStop(), onDestroy(). RequestManager实现了它。
三 如何绑定生命周期
我们来看一下关键代码Glide.with()这个方法
public static RequestManager with(@NonNull Context context)
public static RequestManager with(@NonNull Activity activity)
public static RequestManager with(@NonNull FragmentActivity activity)
public static RequestManager with(@NonNull Fragment fragment)
public static RequestManager with(@NonNull View view)
这里with()方法虽然重载了很多方法,但是只分为两类:
- 传入一个ApplicationContext,Glide的生命周期就相当于绑定了整个应用,只要应用不退出,任何时候都能够加载,也可以理解为不对Glide生命周期进行管理。
- 传入activity、FragmentActivity 、Fragment 及View
,这样就会创建一个看不见的fragment,Glide的生命周期就随着该Fragment的变化而变化
2.1 传入参数为ApplicationContext时
public static RequestManager with(@NonNull Context context) {
return getRetriever(context).get(context);
}
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) {
return get(((ContextWrapper) context).getBaseContext());
}
}
return getApplicationManager(context);
}
因为传入的是ApplicationContext参数类型,所以最终调用了getApplicationManager()方法:
private RequestManager getApplicationManager(Context context) {
if (applicationManager == null) {
synchronized (this) {
if (applicationManager == null) {
applicationManager = new RequestManager(context.getApplicationContext(),
new ApplicationLifecycle(), new EmptyRequestManagerTreeNode());
}
}
}
return applicationManager;
}
这里传入了ApplicationLifecycle来管理生命周期,但是看ApplicationLifecycle源码,只有一个addListener()方法,所以不起控制作用,只有整个app进程退出,Glide的request的生命周期才结束,这显然不是什么优点,所以我们主要来看一下传入Activity或者Fragment的效果
2.2 传入参数类型为Activity为例
Glide.java:
public static RequestManager with(Activity activity) {
RequestManagerRetriever retriever = RequestManagerRetriever.get();
return retriever.get(activity);
}
RequestManagerRetriever.java:
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);
}
}
如果当前是在子线程,则不需要对Glide生命周期进行管理,否则将通过fragmentGet方法创建一个fragment。
RequestManager fragmentGet(Context context, android.app.FragmentManager fm) {
RequestManagerFragment current = getRequestManagerFragment(fm);
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
requestManager = new RequestManager(context, current.getLifecycle(), current.getRequestManagerTreeNode());
current.setRequestManager(requestManager);
}
return requestManager;
}
我们来看一下getRequestManagerFragment()这个方法:
RequestManagerFragment getRequestManagerFragment(final android.app.FragmentManager fm) {
RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
current = pendingRequestManagerFragments.get(fm);
if (current == null) {
current = new RequestManagerFragment();
pendingRequestManagerFragments.put(fm, current);
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
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重复创建,因为每个activity必须对应一个唯一的fragment。来看一下这个fragment的实现RequestManagerFragment。
public class RequestManagerFragment extends Fragment {
private final ActivityFragmentLifecycle lifecycle;
public SupportRequestManagerFragment() {
this(new ActivityFragmentLifecycle());
}
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();
unregisterFragmentWithRoot();
}
...
}
这里将新建一个ActivityFragmentLifecycle,赋值给RequestManagerFragment的 this.lifecycle,在当前fragment的生命周期方法里,会调用ActivityFragmentLifecycle的对应的方法,我们来看一下ActivityFragmentLifecycle:
ActivityFragmentLifecycle.java:
class ActivityFragmentLifecycle implements Lifecycle {
@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();
}
}
}
在ActivityFragmentLifecycle生命周期方法里,会有一个监听回调,调用LifecycleListener对应的生命周期方法,我们在前面说过RequestManager是管理Glide的Request生命周期的管理类,那么在这里我们很自然就联想到,RequestManager应该是实现了LifecycleListener这个接口,才能实现管理的功能,我们来验证一下:
我们倒回去看看RequestManagerRetriever的fragmentGet方法
RequestManager fragmentGet(Context context, android.app.FragmentManager fm) {
RequestManagerFragment current = getRequestManagerFragment(fm);
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
requestManager = new RequestManager(context, current.getLifecycle(), current.getRequestManagerTreeNode());
current.setRequestManager(requestManager);
}
return requestManager;
}
在创建RequestManager的时候传入了新建的RequestManagerFragment的Lifecycle,也就是上面说过的ActivityFragmentLifecycle,我们来看一下RequestManager的构造方法:
RequestManager.java:
public class RequestManager implements LifecycleListener,
ModelTypes<RequestBuilder<Drawable>> {
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;
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的时候,传入了RequestManagerFragment的Lifecycle(ActivityFragmentLifecycle),赋值给RequestManager自己的lifecycle,同时调用ActivityFragmentLifecycle的addListener()方法,把自己作为监听器赋值给ActivityFragmentLifecycle的LifecycleListener。
四 总结
总的来说,当主界面是Activity或者是Fragment的时候,Glide在调用with()方法的时候,会将其作为参数传去,然后Glide会通过RequestManagerRetriever创建一个空白的fragment(RequestManagerFragment),将这个空白的fragment添加到主界面中,这样生命周期就和主界面绑定了;在这个fragment里,会new一个实现了Lifecycle的 ActivityFragmentLifecycle,在调用空白fragment的生命周期方法的同时,会调用ActivityFragmentLifecycle对应的方法,而在ActivityFragmentLifecycle的生命周期方法里,会回调一个监听器对应的方法(LifecycleListener),这个监听器在RequestManagerRetriever这个类里创建RequestManager里被赋值,所以这里通过回调,实现了主界面生命周期和RequestManager实现了绑定。而RequestManager里是通过requestTracker这个类来管理Glide的Request的,代码比较简单,这里就不细说了。
|