news 2026/9/3 7:46:01

android Glide 生命周期详解,怎么停止请求,重新请求

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
android Glide 生命周期详解,怎么停止请求,重新请求

Glide 5.x 生命周期管理完整链路

一、入口:RequestManagerRetriever.get(FragmentActivity)

@NonNull public RequestManager get(@NonNull FragmentActivity activity) { if (Util.isOnBackgroundThread()) { return get(activity.getApplicationContext()); } assertNotDestroyed(activity); frameWaiter.registerSelf(activity); boolean isActivityVisible = isActivityVisible(activity); Glide glide = Glide.get(activity.getApplicationContext()); // 关键变化:不再走 supportFragmentGet,而是走 lifecycleRequestManagerRetriever return lifecycleRequestManagerRetriever.getOrCreate( activity, glide, activity.getLifecycle(), // 直接传入 AndroidX Lifecycle activity.getSupportFragmentManager(), // 用于构建 RequestManagerTreeNode isActivityVisible); }

关键区别:Glide 5.x 不再创建无 UI 的SupportRequestManagerFragment,而是直接利用FragmentActivity已经实现的LifecycleOwner接口,获取其androidx.lifecycle.Lifecycle


二、LifecycleRequestManagerRetriever.getOrCreate()

final class LifecycleRequestManagerRetriever { @Synthetic final Map<Lifecycle, RequestManager> lifecycleToRequestManager = new HashMap<>(); RequestManager getOrCreate( Context context, Glide glide, final Lifecycle lifecycle, // AndroidX Lifecycle FragmentManager childFragmentManager, boolean isParentVisible) { Util.assertMainThread(); // 1. 以 AndroidX Lifecycle 为 key 做缓存 RequestManager result = getOnly(lifecycle); if (result == null) { // 2. 创建桥接对象:将 AndroidX Lifecycle 转为 Glide 的 Lifecycle LifecycleLifecycle glideLifecycle = new LifecycleLifecycle(lifecycle); // 3. 构建 RequestManager,传入 glideLifecycle result = factory.build( glide, glideLifecycle, new SupportRequestManagerTreeNode(childFragmentManager), context); // 4. 缓存 lifecycleToRequestManager.put(lifecycle, result); // 5. 注册一个匿名监听器,用于 onDestroy 时移除缓存 glideLifecycle.addListener(new LifecycleListener() { @Override public void onStart() {} @Override public void onStop() {} @Override public void onDestroy() { lifecycleToRequestManager.remove(lifecycle); } }); // 6. 如果 Activity 当前可见,立即触发 onStart if (isParentVisible) { result.onStart(); } } return result; } }

三、桥接核心:LifecycleLifecycle

LifecycleLifecycle是 Glide 5.x 新增的核心桥接类,一头对接 AndroidXLifecycle,一头对接 Glide 自己的LifecycleListener

final class LifecycleLifecycle implements Lifecycle, LifecycleObserver { @NonNull private final Set<LifecycleListener> lifecycleListeners = new HashSet<>(); @NonNull private final androidx.lifecycle.Lifecycle lifecycle; LifecycleLifecycle(androidx.lifecycle.Lifecycle lifecycle) { this.lifecycle = lifecycle; // 关键:把自己注册为 AndroidX Lifecycle 的观察者 lifecycle.addObserver(this); } // AndroidX Lifecycle 事件回调 @OnLifecycleEvent(Event.ON_START) public void onStart(@NonNull LifecycleOwner owner) { for (LifecycleListener listener : Util.getSnapshot(lifecycleListeners)) { listener.onStart(); } } @OnLifecycleEvent(Event.ON_STOP) public void onStop(@NonNull LifecycleOwner owner) { for (LifecycleListener listener : Util.getSnapshot(lifecycleListeners)) { listener.onStop(); } } @OnLifecycleEvent(Event.ON_DESTROY) public void onDestroy(@NonNull LifecycleOwner owner) { for (LifecycleListener listener : Util.getSnapshot(lifecycleListeners)) { listener.onDestroy(); } owner.getLifecycle().removeObserver(this); } @Override public void addListener(@NonNull LifecycleListener listener) { lifecycleListeners.add(listener); // 根据当前状态立即同步回调,避免状态不一致 if (lifecycle.getCurrentState() == State.DESTROYED) { listener.onDestroy(); } else if (lifecycle.getCurrentState().isAtLeast(State.STARTED)) { listener.onStart(); } else { listener.onStop(); } } }

四、RequestManager如何接收回调?

RequestManager实现了LifecycleListener接口,在构造方法中注册自己:

public class RequestManager implements ComponentCallbacks2, LifecycleListener, ... { RequestManager(Glide glide, Lifecycle lifecycle, ...) { this.lifecycle = lifecycle; // 注册到 LifecycleLifecycle 的监听器集合 lifecycle.addListener(this); lifecycle.addListener(connectivityMonitor); // ... } @Override public void onStart() { resumeRequests(); // 恢复所有暂停的请求 targetTracker.onStart(); } @Override public void onStop() { pauseRequests(); // 暂停所有正在进行的请求 targetTracker.onStop(); } @Override public void onDestroy() { targetTracker.onDestroy(); for (Target<?> target : targetTracker.getAll()) { clear(target); // 清理所有请求,防止内存泄漏 } targetTracker.clear(); } }

五、完整回调链路(Glide 5.x)

Activity.onStart() / Activity.onStop() / Activity.onDestroy() ↓ AndroidX LifecycleRegistry 分发事件 ↓ LifecycleLifecycle(@OnLifecycleEvent 回调) ↓ 遍历 lifecycleListeners 集合 ↓ RequestManager.onStart() / onStop() / onDestroy() ↓ resumeRequests() / pauseRequests() / clear()

六、Glide 5.x 还创建无 UI Fragment 吗?

对于FragmentActivity:❌不再创建SupportRequestManagerFragment。直接使用activity.getLifecycle()

对于Fragment:同样走lifecycleRequestManagerRetriever.getOrCreate(),传入fragment.getLifecycle()

public RequestManager get(@NonNull Fragment fragment) { // ... return lifecycleRequestManagerRetriever.getOrCreate( context, glide, fragment.getLifecycle(), // 直接用 Fragment 的 Lifecycle fragment.getChildFragmentManager(), fragment.isVisible()); }

SupportRequestManagerFragment还在吗?还在,但作用变了:

  • 它仍然是一个无 UI Fragment,内部持有ActivityFragmentLifecycle

  • 但现在主要用于构建RequestManagerTreeNode(管理 Fragment 层级树),以及兼容一些内部场景

  • 对于FragmentActivity本身,不再需要通过它来感知生命周期,因为 AndroidXLifecycle已经足够


七、Glide 4.x vs 5.x 对比

维度Glide 4.xGlide 5.x
FragmentActivity创建SupportRequestManagerFragment直接复用activity.getLifecycle()
Fragment创建SupportRequestManagerFragment直接复用fragment.getLifecycle()
桥接方式ActivityFragmentLifecycle(手动转发)LifecycleLifecycle(桥接 AndroidX)
依赖可选 Support Library强制依赖 AndroidX Lifecycle

一句话总结:Glide 5.x 的生命周期管理已经彻底拥抱 AndroidX Lifecycle,不再需要偷偷往你的 Activity 里塞无 UI Fragment。RequestManageronStart/onStop回调链路是:AndroidX Lifecycle →LifecycleLifecycle(桥接)→RequestManager(LifecycleListener)


三、生命周期自动行为

RequestManager收到生命周期回调后的处理逻辑:

生命周期触发方法行为
onStart()resumeRequests()恢复之前暂停的请求;启动网络监听
onStop()pauseRequests()暂停所有正在进行的请求;释放网络监听
onDestroy()clearRequests()取消并清除所有请求;回收资源;移除监听器

自动场景举例

  • 用户按 Home 键 → ActivityonStop()→ Glide自动暂停所有图片加载

  • 用户返回 App → ActivityonStart()→ Glide自动恢复未完成的加载

  • 用户退出页面 → ActivityonDestroy()→ Glide自动清除请求,防止内存泄漏


四、手动停止请求的 4 种方式

1. 暂停所有请求(保留资源,可恢复)

java

// 在 RequestManager 上调用 RequestManager requestManager = Glide.with(activity); requestManager.pauseRequests(); // 暂停正在运行的请求 requestManager.pauseAllRequests(); // 额外释放已完成请求的 bitmap

适用场景:页面进入后台但未被销毁,想暂时停止加载以节省带宽/CPU。

2. 恢复所有请求

java

requestManager.resumeRequests(); // 恢复之前 pause 的请求

适用场景:页面回到前台,手动触发恢复(通常由生命周期自动处理,无需手动调用)。

3. 清除单个 Target / ImageView

java

// 停止特定 ImageView 的加载,并释放已加载的图片资源 Glide.with(activity).clear(imageView);

适用场景:RecyclerView 的 ViewHolder 复用时,在onViewRecycled()中清除旧请求。

4. 清除所有请求(不可逆)

java

// 在 onDestroy 时自动调用,通常不需要手动调用 requestManager.onDestroy(); // 或 requestTracker.clearRequests()

注意clearRequests()回收请求对象,这些请求不能再被 restart


五、重新请求的 3 种方式

1. 自动重新请求(生命周期驱动)

当 Activity 从onStop()回到onStart()时,RequestTracker.resumeRequests()会自动遍历所有未完成的请求并调用request.begin()

java

// RequestTracker.java public void resumeRequests() { isPaused = false; for (Request request : Util.getSnapshot(requests)) { if (!request.isComplete() && !request.isRunning()) { request.begin(); // 重新启动 } } pendingRequests.clear(); }
2. 重启失败的/取消的/正在进行的请求

java

// RequestTracker.restartRequests() public void restartRequests() { for (Request request : Util.getSnapshot(requests)) { if (!request.isComplete() && !request.isCleared()) { request.clear(); if (!isPaused) { request.begin(); } else { pendingRequests.add(request); // 等 onResume 再启动 } } } }

适用场景:网络恢复、用户手动下拉刷新时,想强制重试所有未完成请求。

3. 手动重新发起加载(最常用)

java

// 直接重新调用 load,Glide 会自动取消该 ImageView 上的旧请求 Glide.with(activity) .load(newUrl) .placeholder(R.drawable.loading) .error(R.drawable.error) .into(imageView);

Glide 内部机制into(imageView)时,会先执行clear(imageView)取消旧请求,再启动新请求。因此无需手动 clear 再 load


六、网络状态监听与自动重试

Glide 还会监听网络连接状态(需ACCESS_NETWORK_STATE权限):

  • 网络断开时:请求失败进入 pending

  • 网络恢复时:ConnectivityListener回调 → 自动调用restartRequests()


七、实战代码示例

场景 1:RecyclerView 中手动管理

java

@Override public void onViewRecycled(@NonNull ViewHolder holder) { super.onViewRecycled(holder); // 停止该 ViewHolder 的图片加载,防止复用时显示旧图 Glide.with(fragment).clear(holder.imageView); } @Override public void onBindViewHolder(@NonNull ViewHolder holder, int position) { String url = dataList.get(position); // 重新请求,旧请求会自动被清除 Glide.with(fragment) .load(url) .into(holder.imageView); }
场景 2:手动暂停/恢复(如 ViewPager 切换)

java

public class MyFragment extends Fragment { private RequestManager requestManager; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestManager = Glide.with(this); } @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); if (isVisibleToUser) { requestManager.resumeRequests(); // 可见时恢复 } else { requestManager.pauseRequests(); // 不可见时暂停 } } }
场景 3:页面销毁前手动清理

java

@Override public void onDestroyView() { super.onDestroyView(); // 清除该页面所有请求(通常 onDestroy 会自动处理,但可手动保险) Glide.with(this).onDestroy(); }

八、总结

操作API是否可恢复说明
自动暂停生命周期onStop()页面不可见时自动触发
自动恢复生命周期onStart()页面可见时自动触发
手动暂停pauseRequests()临时节省资源
手动恢复resumeRequests()与 pause 配对使用
清除单个clear(imageView)需重新load().into()
重启所有restartRequests()重试失败/暂停的请求
销毁所有onDestroy()/clearRequests()页面销毁,资源回收

核心设计思想:Glide 把生命周期管理做成了自动挡,开发者通常只需Glide.with(activity).load(url).into(iv),其余暂停、恢复、清理都由框架自动处理。只有在 RecyclerView、ViewPager 等特殊场景下,才需要手动介入。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/3 7:45:52

基于UNet与PyQt5的CT脾脏分割桌面系统开发实战

简介&#xff1a;本资源是一套面向医学影像处理初学者与临床辅助开发者的桌面级CT脾脏分割系统&#xff0c;基于UNet深度学习模型与PyQt5构建完整GUI应用&#xff0c;解决医学图像中脾脏区域自动识别与可视化标注的实际需求。资源包共1143个文件&#xff0c;含569张PNG、559张J…

作者头像 李华
网站建设 2026/9/3 7:44:54

基于MATLAB/Simulink的仿生四足机器人仿真系统设计与实践

简介&#xff1a;本资源是一套面向机器人控制方向本科生、研究生及科研初学者的仿生四足机器人全流程仿真教学与开发参考系统&#xff0c;聚焦动态建模、步态规划、动力学仿真与PID运动控制等核心难点&#xff0c;解决从理论建模到Simulink可视化验证的实践断层问题。压缩包共1…

作者头像 李华
网站建设 2026/9/3 7:41:42

C#运动控制上位机开发:基于GTS控制卡的实战架构与核心功能实现

简介&#xff1a;本资源是面向工业自动化领域C#开发工程师与运动控制初学者的GTS系列运动控制器实战编程包&#xff0c;聚焦伺服系统集成、多轴同步控制及轨迹规划等核心场景。压缩包共849个文件&#xff0c;含154个C#源码文件&#xff08;.cs&#xff09;、32个Visual Studio解…

作者头像 李华
网站建设 2026/9/3 7:37:19

SpringDataRedis 操作 redis

Spring Data Redis 完全按照 Redis 的数据类型做了模块化封装&#xff0c;和原生命令一一对应。 下面我按「通用Key操作 5大核心数据类型」分类整理&#xff0c;每个方法都标注等价的 Redis 原生命令和可直接运行的代码示例&#xff0c;方便你对照记忆。一、通用 Key 操作&…

作者头像 李华