Glide原理--生命周期绑定

Gilde 的使用

最基础的使用

Glide.with(context).load(url).into(imageView)

with方法

Glide.with(context)
with 重载方法
with(android.app.Activity)
with(android.app.Fragment)
with(android.support.v4.app.Fragment)
with(android.support.v4.app.FragmentActivity)
with(android.view)

with 方法返回的都是一个RequestManager对象,RequestManager 是管理请求的

@NonNull
  public static RequestManager with(@NonNull Activity activity) {
    return getRetriever(activity).get(activity);
  }

get 方法 根据不同的context 返回不同的RequestManager

public RequestManager get(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) {
            return get(((ContextWrapper) context).getBaseContext());
        }
    }

    return getApplicationManager(context);
}

如果context是activity ,继续看

public RequestManager get(@NonNull Activity activity) {
  if (Util.isOnBackgroundThread()) {
    // 如果不是主线程,则context对象转为ApplicationContext,然后也不做绑定生命周期的操作,
    // 图片加载的生命周期默认为Application的生命周期
    return get(activity.getApplicationContext());
  } else {
    assertNotDestroyed(activity);
    //(1)
    android.app.FragmentManager fm = activity.getFragmentManager();
    return fragmentGet(activity, fm, null /*parentHint*/);
  }
}
  • (1)处通过activity 获取了FragmentManager 并传给了fragmentGet方法
    fragmentGet 方法
private RequestManager fragmentGet(@NonNull Context context,
    @NonNull android.app.FragmentManager fm,
    @Nullable android.app.Fragment parentHint) {
    //(1)
  RequestManagerFragment current = getRequestManagerFragment(fm, parentHint);
  RequestManager requestManager = current.getRequestManager();
  ......
  return requestManager;
}
  • (1)处 获取到一个无UI的Fragment,用来绑定Activity从而实现生命周期同步
创建Fragment 的原因
  • 因为glide无法直接获取activity的生命周期,通过activity的FragmentManager中加入一个隐藏的fragment,因为fragment与传入的activity生命周期一致,所以只要监听这个RequestManagerFragment就能实现生命周期管理

接下来 getRequestManagerFragment 创建fragment

RequestManagerFragment getRequestManagerFragment(
    @NonNull final android.app.FragmentManager fm, @Nullable android.app.Fragment parentHint) {
//(1)
  RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
  //(2)
  if (current == null) {
    current = pendingRequestManagerFragments.get(fm);
    if (current == null) {//(3)
      current = new RequestManagerFragment();
      ......
    }
  }
  return current;
} 
  • (1)处 这个Fragment是个无UI的Fragment,可以通过findFragmentByTag(FRAGMENT_TAG)去查找这个RequestManagerFragment
  • (2)处 如果第一次进来,current就是null,如果已经创建过,可以通过fm对象找到已有的fragment对象,如果再没有(3)就创建一个RequestManagerFragment

接下来RequestManagerFragment 的构造方法

public class SupportRequestManagerFragment extends Fragment {
  
  public SupportRequestManagerFragment() {
   //(1)
    this(new ActivityFragmentLifecycle());
  }

  @SuppressLint("ValidFragment")
  public SupportRequestManagerFragment(ActivityFragmentLifecycle lifecycle) {
    //(2)
    this.lifecycle = lifecycle;
  }

  ActivityFragmentLifecycle getGlideLifecycle() {
    return lifecycle;
  }

  @Override
  public void onStart() {
    super.onStart();
    lifecycle.onStart();//(3)
  }

  @Override
  public void onStop() {
    super.onStop();
    lifecycle.onStop();//(4)
  }

  @Override
  public void onDestroy() {
    super.onDestroy();
    lifecycle.onDestroy();//(5)
  }
}
  • (1)处 初始化Fragment的时候也顺便初始化了ActivityFragmentLifecycle
  • (2)处 lifecycle赋值 ActivityFragmentLifecycle
  • (3)(4)(5) 处都是fragement 生命周期的回调方法,在生命周期方法中调用ActivityFragmentLifecycle 的生命周期方法

看下ActivityFragmentLifecycle

class ActivityFragmentLifecycle implements Lifecycle {
  
  @Override
  public void addListener(LifecycleListener listener) {
    lifecycleListeners.add(listener);

    if (isDestroyed) {
      listener.onDestroy();
    } else if (isStarted) {
      listener.onStart();
    } else {
      listener.onStop();
    }
  }

  @Override
  public void removeListener(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();
    }
  }
}

public interface Lifecycle {
  void addListener(LifecycleListener listener);
  void removeListener(LifecycleListener listener);
}
  • ActivityFragmentLifecycle 实现了Lifecycle
  • 对外暴露一个addListener方法,可以监听生命周期的变化
  • ActivityFragmentLifecycle 中的生命周期方法又调用了传递进来的lifecycleListener 的生命周期方法

看下哪里调用了addListener ,在开始的fragmentGet中

private RequestManager fragmentGet(@NonNull Context context,
    @NonNull android.app.FragmentManager fm,
    @Nullable android.app.Fragment parentHint) {
  RequestManagerFragment current = getRequestManagerFragment(fm, parentHint);
  RequestManager requestManager = current.getRequestManager();
  if (requestManager == null) {
    Glide glide = Glide.get(context);
    //(1)
    requestManager = factory.build(
            glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
    current.setRequestManager(requestManager);
  }
  return requestManager;
}
  • (1) 处 传入的current.getGlideLifecycle() 就是Lifecycle ,而lifecycle正是ActivityFragmentLifecycle。

RequestManagerFactory

public interface RequestManagerFactory {
  @NonNull
  RequestManager build(
      @NonNull Glide glide,
      @NonNull Lifecycle lifecycle,
      @NonNull RequestManagerTreeNode requestManagerTreeNode,
      @NonNull Context context);
}

private static final RequestManagerFactory DEFAULT_FACTORY = new RequestManagerFactory() {
  @NonNull
  @Override
  public RequestManager build(@NonNull Glide glide, @NonNull Lifecycle lifecycle,
      @NonNull RequestManagerTreeNode requestManagerTreeNode, @NonNull Context context) {
    // (1)
    return new RequestManager(glide, lifecycle, requestManagerTreeNode, context);
  }
};
  • (1) 处 初始化了RequestManager

看下 RequestManager

public class RequestManager implements LifecycleListener {

  RequestManager(
      Glide glide,
      Lifecycle lifecycle,
      RequestManagerTreeNode treeNode,
      RequestTracker requestTracker,
      ConnectivityMonitorFactory factory,
      Context context) {

    this.glide = glide;
    this.lifecycle = lifecycle;
    this.treeNode = treeNode;
    this.requestTracker = requestTracker;
    this.context = context;

    if (Util.isOnBackgroundThread()) {
      mainHandler.post(addSelfToLifecycle);
    } else {
      // (1)
      lifecycle.addListener(this);
    }
  }
  ...
  @Override
  public void onDestroy() {
    targetTracker.onDestroy();
    for (Target<?> target : targetTracker.getAll()) {
      clear(target);
    }
    targetTracker.clear();
    requestTracker.clearRequests();
    lifecycle.removeListener(this);
    lifecycle.removeListener(connectivityMonitor);
    mainHandler.removeCallbacks(addSelfToLifecycle);
    glide.unregisterRequestManager(this);
  }
}
  • (1)处 调用lifecycle.addListener(this); 实现了与RequestManagerFragment生命周期的绑定
类之间关系图:

在这里插入图片描述

<think>我们正在讨论Glide.with方法绑定生命周期对象及其影响。根据引用内容,我们可以总结如下: 1. **绑定对象**:Glide.with()方法可以接受多种上下文参数,包括Activity、Fragment、FragmentActivity、Context、View等。但实际绑定生命周期对象取决于参数类型: - 当参数是Activity或Fragment时,直接使用其生命周期- 当参数是Context(非Activity)或View时,Glide会尝试判断上下文环境。如果该Context属于一个Activity或Fragment,则创建一个无界面的SupportRequestManagerFragment(或RequestManagerFragment)并附加到该Activity上,从而绑定生命周期;否则,不会绑定生命周期(使用Application级别的生命周期)。 2. **绑定后的影响**: -绑定生命周期对象(如Activity)进入onStop时,Glide会暂停图片加载请求。 -生命周期对象进入onStart时,恢复暂停的请求(如果配置了在onStart时恢复)。 -生命周期对象进入onDestroy时,自动取消所有未完成的请求并清理相关资源,避免内存泄漏。 具体步骤分析(根据引用[1][3][4]): - 调用`Glide.with(activity)`时,会通过`RequestManagerRetriever`获取一个`RequestManager`。 - `RequestManagerRetriever`会创建一个无UI的`SupportRequestManagerFragment`(对于FragmentActivity)或`RequestManagerFragment`(对于Activity),并将其添加到Activity中。 - 这个Fragment内部持有`Lifecycle`对象,并将自己的生命周期事件通过`LifecycleListener`接口传递给`RequestManager`。 - `RequestManager`注册为生命周期的观察者,从而在生命周期变化时执行相应操作(暂停、恢复、清除请求)。 影响总结: - **避免内存泄漏**:通过绑定生命周期,确保在Activity/Fragment销毁时自动释放所有相关资源。 - **优化性能**:在不可见时(如onStop)暂停加载,减少不必要的网络请求和CPU消耗。 - **智能恢复**:当Activity回到前台时,自动恢复加载任务(需配置)。 相关问题: 1. Glide如何确保在非Activity上下文中也能安全使用? 2. 如果Activity被销毁重建,Glide如何处理已加载的图片? 3. 如何自定义Glide生命周期绑定行为? </think>### Glide.with() 绑定生命周期对象及影响分析 #### 一、生命周期绑定对象 1. **Activity/Fragment 对象** `Glide.with(activity)` 或 `Glide.with(fragment)` 直接绑定传入的 Activity/Fragment 生命周期[^1][^3]。 - **原理**:创建无界面的 `SupportRequestManagerFragment` 添加到 Activity - **关键类**:通过 `RequestManagerRetriever` 获取 `RequestManager`[^2] 2. **View/Context 对象** `Glide.with(view)` 或 `Glide.with(context)`: - 自动向上查找宿主 Activity(通过 View.getContext() 或 Context 层级) - 若找到 Activity,绑定生命周期;否则使用 Application 级作用域[^4][^3] #### 二、绑定后的核心影响 1. **自动暂停/恢复加载** - ⏹️ `onStop()`:暂停所有网络请求和磁盘加载 - ▶️ `onStart()`:恢复未完成的任务(需配置 `onlyRetrieveFromCache(false)`)[^3] ```java // 伪代码:生命周期事件传递 fragment.onStop() → Lifecycle.onStop() → RequestManager.onStop() → 暂停引擎任务 ``` 2. **内存泄漏防护** - `onDestroy()`:自动取消所有请求,释放 Bitmap 引用 - 弱引用机制确保 Activity 销毁时请求被 GC 回收[^1][^3] 3. **缓存策略联动** - 绑定 Activity 时:内存缓存跟随生命周期清除(非 Application 级缓存) - 绑定 Application 时:全局缓存持久化[^2] 4. **线程调度优化** - ⚡ 主线程请求自动切换到 IO 线程加载 - 生命周期结束时终止后台线程任务[^1] #### 三、特殊场景影响 | **绑定对象类型** | **网络加载** | **内存缓存** | **生命周期感知** | |----------------|-------------|-------------|----------------| | Activity | 暂停/恢复 | 局部缓存 | ✔️ 完整感知 | | Application | 持续加载 | 全局缓存 | ❌ 无感知 | | 无宿主 Context | 持续加载 | 全局缓存 | ❌ 无感知 | > **示例**:在 `RecyclerView` 中使用时推荐绑定 `RecyclerView` 自身,Glide 会自动查找其宿主 Activity 实现生命周期绑定: > ```kotlin > holder.itemView.context?.let { > Glide.with(it).load(url).into(holder.imageView) > } // 自动关联 RecyclerView 所在 Activity > ``` #### 四、注意事项 1. **避免内存泄漏** 使用 `ApplicationContext` 的场景需手动管理资源,否则可能泄漏[^3]: ```java // 错误示例(可能泄漏): Glide.with(getApplicationContext()).load(url).into(imageView); // 正确做法(主动清理): RequestManager requestManager = Glide.with(getApplicationContext()); requestManager.load(url).into(imageView); onDestroy() { requestManager.clear(imageView); } ``` 2. **Fragment 特殊处理** `ViewPager` 中的 Fragment 需使用 `getChildFragmentManager()` 绑定,否则可能绑定到父 Activity 导致生命周期错乱[^4]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值