Glide中一个重要特性是Request可以随Activity或Fragment的onStart而resume,onStop而pause,onDestroy而clear,从而节约流量和内存,并且防止内存泄露,这一切都由Glide在内部实现了,前提是Glide.with()方法中尽量传入Activity或Fragment,而不是Application,不然没办法进行生命周期管理
而现在,我自己就有这种需求,所以我需要去看一下Glide是如何实现这一功能的
首先是Glide.with()方法
public static RequestManager with(Activity activity) {
RequestManagerRetriever retriever = RequestManagerRetriever.get();
return retriever.get(activity);
}
这里的RequestManagerRetriever.get()方法是获取了RequestManagerRetriever的对象,而这个类的对象的作用
/**
* A collection of static methods for creating new {@link com.bumptech.glide.RequestManager}s or retrieving existing
* ones from activities and fragment.
*/
public class RequestManagerRetriever implements Handler.Callback如备注所说,是用于创建一个新的RequestManager或者从Activity或Fragment获取一个已经存在的
RequestManager对象
而到了retriver.get(activity)进去看一下
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public RequestManager get(Activity activity) {
//这里首先判断是否在主线程,以及当前的版本是否小于HONEYCOMB(11---> 3.0.x)
if (Util.isOnBackgroundThread() || Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
return get(activity.getApplicationContext());
} else {//发现是主线程并且当前版本大于等于11(Android 3.0.x)时
assertNotDestroyed(activity);//如果当前版本大于等于17(4.2)并且activity已经destroy,就会抛出错误
android.app.FragmentManager fm = activity.getFragmentManager();
return fragmentGet(activity, fm);
}
}在第一个判断中,满足条件的话,即在子现成,或者版本小于11时,会直接走
getApplicationManager(context)
这一条路线就跟监听Activity生命周期无关了,所以不看
而另一条路线我们继续
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
RequestManager fragmentGet(Context context, android.app.FragmentManager fm) {
//
RequestManagerFragment current = getRequestManagerFragment(fm);//获取空白的Fragment
RequestManager requestManager = current.getRequestManager();//获取空白Fragment中的RequestManager
if (requestManager == null) {
//发现没有RequestManager则立刻新建一个,新建时,将自己的Lifecycler传入
requestManager = new RequestManager(context, current.getLifecycle(), current.getRequestManagerTreeNode());
current.setRequestManager(requestManager);
}
return requestManager;
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
RequestManagerFragment getRequestManagerFragment(final android.app.FragmentManager fm) {
//根据tag找到已经添加的Fragment
RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
//根据FragmentManager对象去本地管理的缓存中寻找Fragment
current = pendingRequestManagerFragments.get(fm);
if (current == null) {//还是没有找到,则新建
current = new RequestManagerFragment();
pendingRequestManagerFragments.put(fm, current);
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();//添加Fragment
handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();//进入队列去删除FragmentManager
}
}
return current;
}
@Override
public boolean handleMessage(Message message) {
boolean handled = true;
Object removed = null;
Object key = null;
switch (message.what) {
case ID_REMOVE_FRAGMENT_MANAGER:
android.app.FragmentManager fm = (android.app.FragmentManager) message.obj;
key = fm;
// fragment创建好后,将之前的FragmentManager删除掉,因为已经用不上它了,同一个Activity或父Fragment中只会创建一个SupportRequestManagerFragment
removed = pendingRequestManagerFragments.remove(fm);
break;
case ID_REMOVE_SUPPORT_FRAGMENT_MANAGER:
FragmentManager supportFm = (FragmentManager) message.obj;
key = supportFm;
removed = pendingSupportRequestManagerFragments.remove(supportFm);
break;
default:
handled = false;
}
if (handled && removed == null && Log.isLoggable(TAG, Log.WARN)) {
Log.w(TAG, "Failed to remove expected request manager fragment, manager: " + key);
}
return handled;
}
可以看到,这边就是一个新建空白Fragment并将空白Fragment与RequestManager绑定的过程
到了这里,基本原理已经清楚了,因为到了这里已经给Activity添加了一个Fragment,已经可以从自定义的Fragment中获取各个生命周期了,那么哪些生命周期比较准确呢?我们需要一个Fragment与Activity的生命周期的关系图:
有了这个生命周期的对照,有了之前到绑定的逻辑,其实已经可以自己写出来了,神奇的监听生命周期的核心就在于添加一个
Fragment,之后的就是在Fragment的各个生命周期进行通知回调即可,至于其他的细节处理,就不是那么重要了
那么,接下来我就自己写一个监听试试看
首先是框架方面我需要哪几个类
SupportActLifeListenerFragment空白的Fragment,用于获取Activity的生命周期
ActLifeListenerManager用于管理ActListener以及生命周期的回调执行
ActListener用于给外部传入的回调接口的母类
ActLifeListener extends ActListener用于监听Activity或Fragment的生命周期的接口
LifeAttchManager用于给指定的Activity添加生命周期的监听的开放调用类
然后大概是什么个流程
流程相当简单,只是因为关系到Activity,所以需要注意不要持有Activity导致无法回收等问题
代码我就不直接贴了,可以去我的github项目上去看,运行的demo为:demoactivitylifelistener