为什么使用Glide
- Glide是Google为我们推荐的图片加载框架,有强大的后援支持,有人维护更新
- Glide太好用了,用法简单、功能强大,with、load、into完成一切操作
- 与生命周期绑定,缓存机制(高频面试问题)
简单使用:
Glide.with(this) // 空白的fragment管理生命周期机制
.load(url) // 构建出RequestBuilder对象
.into(imageView); // 运行队列、活动缓存、 内存缓存、 网络模型
下面是Glide的整体简化图(非Application作用域)
Glide的用法比较简单本文不做记录,本篇文章主要分析Glide的生命周期机制,下篇文章分析缓存机制
生命周期分析
咱们从 Glide.with(this) 入手
@NonNull
public static RequestManager with(@NonNull Context context) {
return getRetriever(context).get(context);
}
with() 的重载函数比较多,但代码一样。此处信息不多,with函数返回的是个 RequestManager 对象
深入看下 getRetriever(context) 的实现
@NonNull
private static RequestManagerRetriever getRetriever(@Nullable Context context) {
// Context could be null for other reasons (ie the user passes in null), but in practice it will
// only occur due to errors with the Fragment lifecycle.
// 此处是个判空处理,没啥用
Preconditions.checkNotNull(
context,
"You cannot start a load on a not yet attached View or a Fragment where getActivity() "
+ "returns null (which usually occurs when getActivity() is called before the Fragment "
+ "is attached or after the Fragment is destroyed).");
// 分析这里
return Glide.get(context).getRequestManagerRetriever();
}
/**
* Get the singleton.
* @return the singleton
*/
@NonNull
public static Glide get(@NonNull Context context) {
if (glide == null) {
GeneratedAppGlideModule annotationGeneratedModule =
getAnnotationGeneratedGlideModules(context.getApplicationContext());
synchronized (Glide.class) {
if (glide == null) {
checkAndInitializeGlide(context, annotationGeneratedModule);
}
}
}
return glide;
}
/** Internal method. */
@NonNull
public RequestManagerRetriever getRequestManagerRetriever() {
return requestManagerRetriever;
}
分析下上面三段代码:
- 获得 glide的单例对象,有的话返回,没有则创建
- 返回参数 requestManagerRetriever 对象
继续分析 getRetriever(context).get(context) ====》requestManagerRetriever.get(context),看下 requestManagerRetriever 的 get函数实现
@NonNull
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
// Only unwrap a ContextWrapper if the baseContext has a non-null application context.
// Context#createPackageContext may return a Context without an Application instance,
// in which case a ContextWrapper may be used to attach one.
&& ((ContextWrapper) context).getBaseContext().getApplicationContext() != null) {
return get(((ContextWrapper) context).getBaseContext());
}
}
return getApplicationManager(context);
}
@NonNull
public RequestManager get(@NonNull FragmentActivity activity) {
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
FragmentManager fm = activity.getSupportFragmentManager();
return supportFragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
}
}
此处的重载函数有一摞,表达的意思比较简单
- 判断是 context 的来源,是 Application 还是 非Application
- 判断是 主线程 还是 子线程
如果 context 是 Application的 或 Glide在子线程中调用,则生命周期与APP相同,缓存随着APP的销毁而回收!
如果 context 是 非Application的 且 Glide 在主线程中调用,则会创建一个空白的Fragment与当前Activity绑定,缓存随Activity的Destroy调用回收!
ps:下面咱们把它区分为两个作用域,红色区域为Application作用域,绿色区域为非Application作用域
咱们先看红色区域(Application作用域)的实现 getApplicationManager(context)
@NonNull
private RequestManager getApplicationManager(@NonNull Context context) {
// Either an application context or we're on a background thread.
if (applicationManager == null) {
synchronized (this) {
if (applicationManager == null) {
Glide glide = Glide.get(context.getApplicationContext());
applicationManager =
factory.build(
glide,
new ApplicationLifecycle(),
new EmptyRequestManagerTreeNode(),
context.getApplicationContext());
}
}
}
return applicationManager;
}
判空后直接返回了 RequestManager ,没有附加 Fragment ,即不会与当前Activity生命周期绑定
再看看绿色区域(非Application作用域)的逻辑 supportFragmentGet(activity, fm, /parentHint=/ null, isActivityVisible(activity))
@NonNull
private RequestManager supportFragmentGet(
@NonNull Context context,
@NonNull FragmentManager fm,
@Nullable Fragment parentHint,
boolean isParentVisible) {
// 获取 fragment
SupportRequestManagerFragment current =
getSupportRequestManagerFragment(fm, parentHint, isParentVisible);
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
// TODO(b/27524013): Factor out this Glide.get() call.
Glide glide = Glide.get(context);
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
// RequestManager 实现 LifecycleListener 接口, 让 SupportRequestManagerFragment 持有 requestManager
current.setRequestManager(requestManager);
}
return requestManager;
}
此处逻辑:
- 获取 Fragment
- 获取 requestManager ,有的话直接返回,没有的话则构造出来并交给 Fragment 持有
看下 Fragment 的获取逻辑处理 getSupportRequestManagerFragment(fm, parentHint, isParentVisible)
@NonNull
private SupportRequestManagerFragment getSupportRequestManagerFragment(
@NonNull final FragmentManager fm, @Nullable Fragment parentHint, boolean isParentVisible) {
SupportRequestManagerFragment current =
(SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
current = pendingSupportRequestManagerFragments.get(fm);
if (current == null) {
current = new SupportRequestManagerFragment();
current.setParentFragmentHint(parentHint);
if (isParentVisible) {
current.getGlideLifecycle().onStart();
}
pendingSupportRequestManagerFragments.put(fm, current);
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
}
}
return current;
}
//-------------------- handller 处理-------------------------------
case ID_REMOVE_SUPPORT_FRAGMENT_MANAGER:
FragmentManager supportFm = (FragmentManager) message.obj;
key = supportFm;
removed = pendingSupportRequestManagerFragments.remove(supportFm);
break;
上面这段代码要解决的问题只有一个,确保Fragment唯一性,逻辑实现:
- 根据 FRAGMENT_TAG 去 FragmentManager 中寻找,有的话返回
- 在 pendingSupportRequestManagerFragments(是个HashMap) 的缓存中寻找,如果有返回
- 在以上步骤中都没有的话,则new出来一个,带着 FRAGMENT_TAG 提交到事务,为确保立即执行用handler了message,handler收到后移除pendingSupportRequestManagerFragments中的对象
关于Handler说明:fragment事务提交后并不一定会立马执行,Handler发送一次消息促使其执行,fragment与activity实现绑定后删除 pendingSupportRequestManagerFragments 中的缓存,以后再获取的话直接用TAG即可,不需要缓存!
简单看下 SupportRequestManagerFragment 的实现
public class SupportRequestManagerFragment extends Fragment {
...
private final ActivityFragmentLifecycle 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();
}
...
...
}
看吧,在其生命周期函数调用 lifecycle 实现Glide与Activity的生命周期绑定,下面是 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);
}
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();
}
}
}
// ---------------------------------- 接口 Lifecycle 实现 ----------------------------------
public interface Lifecycle {
void addListener(@NonNull LifecycleListener listener);
void removeListener(@NonNull LifecycleListener listener);
}
代码看到这里基本也就明白了,ActivityFragmentLifecycle 实现 Lifecycle 接口,维护一个 Set集合lifecycleListeners ,有与Activity生命周期对应的onStart、onStop、onDestroy三个函数,在其中遍历集合 lifecycleListeners,实现Activity生命周期调用
生命周期绑定、调用关系
函数调用关系