Ahab's Studio.

Glide 源码分析 - 感知生命周期

字数统计: 633阅读时长: 2 min
2019/02/17 Share

发起一个图片加载请求后,我们期望当该请求所处的界面 onStop 时请求也随之停止,再次 onStart 时请求能够随之继续, onDestroy 时请求能够随之销毁。这就需要能够感知当前 Activity 的生命周期变化,由于 Fragment 在 onAttach 之后与 Activity 有相同的生命周期,glide 利用这一点,通过给 Activity 添加一个无界面的 Fragment 实现感知。

发起请求时通过 with 方法传入上下文,此方法会返回一个 RequestManager,RequestManager 用于管理和启动图片加载请求,可以感知外部 Activity 的生命周期,从而管理请求随之启动、停止和重启。

先来分析一个较为简单的流程:with 方法传入 Activity,会调用到 RequestManagerRetriever 的 get 方法:

1
2
3
4
5
6
7
8
9
10
11
@NonNull
public RequestManager get(@NonNull Activity activity) {
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
android.app.FragmentManager fm = activity.getFragmentManager();
return fragmentGet(
activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
}
}

其中调用 fragmentGet 方法去新建 RequestManager :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@NonNull
private RequestManager fragmentGet(@NonNull Context context,
@NonNull android.app.FragmentManager fm,
@Nullable android.app.Fragment parentHint,
boolean isParentVisible) {
//这里新建了一个无界面的 Fragment,并添加到该界面
RequestManagerFragment current = getRequestManagerFragment(fm, parentHint, isParentVisible);
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
Glide glide = Glide.get(context);
requestManager =
//这里新建了一个 requestManager,并将无界面 Fragment 的生命周期暴露给 requestManager
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
current.setRequestManager(requestManager);
}
return requestManager;
}

当无界面 Fragment 生命周期变化时,通过接口回调出去给 requestManager,这样 requestManager 就实现了随外部生命周期变化自动启动、停止和重启请求。with 方法若传入其他参数,流程上也是大同小异,都是找到当前 Activity 或 Fragment ,给其添加一个无界面 Fragment 罢了。

而不管传入何参数,都有这样一个逻辑:

1
2
3
if (Util.isOnBackgroundThread()) {
return get(view.getContext().getApplicationContext());
}

若当前处于非主线程,则一律基于应用生命周期请求,不再关心所在 Fragment 或 Activity 的生命周期,这是因为子线程中执行的任务本身就是跟所在界面生命周期无关的。

在分析这一块时涉及 ContextWrapper 相关的逻辑,若不太熟悉,可参考:ContextWrapper

Glide 推出时谷歌还未发布 Architecture Components,而现在若要实现一个可感知生命周期的逻辑,大可不必像 Glide 一样添加一个 Fragment ,直接使用 Architecture Components 中的 Lifecycle 组件就可以很方便的实现了。

关注公众号,Get 更多知识点

原文作者:Ahab

原文链接:http://yhaowa.gitee.io/c135648c/

发表日期:February 17th 2019, 4:20:28 pm

更新日期:April 7th 2020, 11:34:42 pm

版权声明:本文采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可

CATALOG