Glide源码分析(一) 图片加载的生命周期
在Glide中,图片的加载会跟随这Activity或者Fragment的生命周期进行相应的加载,停止等操作,本节我们通过源码来分析一下Glide是怎么做到这点的
用法
在我的GlideSample中的StartActivity
类中
Glide.with(StartActivity.this).load(R.mipmap.pizza).into(mIvShow);
分析
// 使用的上下文Context,可以是Application,Activity,Fragment实例
Glide.with()
我们看到源码,这里传入的5种类型参数
with(Context context) // any Context
with(android.app.Activity)
with(android.app.Fragment)
with(android.support.v4.app.Fragment)
with(android.support.v4.app.FragmentActivity)
我们以with(android.support.v4.app.FragmentActivity)
为例看下
public static RequestManager with(Activity activity) {
RequestManagerRetriever retriever = RequestManagerRetriever.get();
return retriever.get(activity);
}
接着看下retriever.get(activity)方法
public RequestManager get(FragmentActivity activity) {
if (Util.isOnBackgroundThread()) {
// 不在主线程,返回一个ApplicationContext关联的RequestManager
return get(activity.getApplicationContext());
} else {
// 重点在这里,我们返回一个Fragment相关的RequestManager
assertNotDestroyed(activity);
// 获取activity对应的FragmentManager,主要目的是和Activity结合,
// 塞入一个空的fragment对象,用于暴露出生命周期方法,这个在后面会看到
FragmentManager fm = activity.getSupportFragmentManager();
return supportFragmentGet(activity, fm);
}
}
这里我们很明显的看到如果调用with()方法的时候不是在主线程,那么我们会返回一个和ApplicationContext关联的RequestManager
private RequestManager getApplicationManager(Context context) {
// Either an application context or we're on a background thread.
if (applicationManager == null) {
synchronized (this) {
if (applicationManager == null) {
// Normally pause/resume is taken care of by the fragment we add to the fragment or activity.
// However, in this case since the manager attached to the application will not receive lifecycle
// events, we must force the manager to start resumed using ApplicationLifecycle.
applicationManager = new RequestManager(context.getApplicationContext(),
new ApplicationLifecycle(), new EmptyRequestManagerTreeNode());
}
}
}
return applicationManager;
}
如果是在主线程操作,那么我们会返回一个Fragment相关的RequestManager,这里涉及到一个很精妙的用法,怎样将Activity的生命周期暴露出来与你的封装控件结合使用
RequestManager supportFragmentGet(Context context, FragmentManager fm) {
// 获取一个自定义的Fragment
SupportRequestManagerFragment current = getSupportRequestManagerFragment(fm);
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
// 生成RequestManager对象,看看,这里暴露出了Lifecycle接口,LIfecycle实现类中是一个监听LifecycleListener
requestManager = new RequestManager(context, current.getLifecycle(), current.getRequestManagerTreeNode());
current.setRequestManager(requestManager);
}
return requestManager;
}
SupportRequestManagerFragment中关联了一个Lifecycle接口的实现类ActivityFragmentLifecycle
public SupportRequestManagerFragment() {
this(new ActivityFragmentLifecycle());
}
其中,ActivityFragmentLifecycle类对外提供了添加监听的方法
@Override
public void addListener(LifecycleListener listener) {
......
}
并且ActivityFragmentLifecycle类方法加入到了这个Fragment的生命周期中,如下所示
@Override
public void onStart() {
super.onStart();
lifecycle.onStart();
}
@Override
public void onStop() {
super.onStop();
lifecycle.onStop();
}
@Override
public void onDestroy() {
super.onDestroy();
lifecycle.onDestroy();
}
最终在ActivityFragmentLifecycle中调用了监听中的对应的生命周期方法
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();
}
}
看到没,只要添加了监听实现类,就能获取到对应的生命周期,从而对外提供了生命周期方法
总结
看过源代码,给我一个什么启示,由于Fragment在onAttach()之后,与Activity有相同的生命周期,那么我们就可以通过给Activity添加一个不显示界面的fragment,并且在生命周期方法中,调用暴露的监听的对应方法,这样来达到对外暴露生命周期方法的目的,怎么样,是不是挺巧妙的
好了,这里就先讲解到这里了,后面我们会继续根据介绍暴露出来的接口,怎么跟图片加载结合在一起