美文网首页
Glide的源码分析

Glide的源码分析

作者: 飘絮无意 | 来源:发表于2021-11-24 14:46 被阅读0次

glide源码实在太冗杂了,各种设计模式各种封装人都看到了,但是大佬写的确实好用,下面就几条主线分析一下glide做了什么事;

1.通过glide.with 传入context到底为了什么?

RequestManager with = Glide.with(this);
其实传入的context可以分为两大类来分析:
第一类是ApplicationContext,传入ApplicationContext就代表当前的这次请求跟程序的生命周期一致,所以就不会有感知生命周期能力了;
第二类为activity或者fragment,这是我们重点要关注的,面试可能会遇到,下面针对传入activity进行分析;
在RequestManagerRetriever传入activity后会调用里面的get方法,get方面里面会通过activity.getFragmentManager()获取到FragmentManager,接着传入到fragmentGet方面里面;

  @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));
    }
  }

 @NonNull
  private RequestManager fragmentGet(@NonNull Context context,
      @NonNull android.app.FragmentManager fm,
      @Nullable android.app.Fragment parentHint,
      boolean isParentVisible) {
    RequestManagerFragment current = getRequestManagerFragment(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);
      current.setRequestManager(requestManager);
    }
    return requestManager;
  }

在fragmentGet方法里面创建自定义的RequestManagerFragment 它实际是一个fragment,这个也是感知生命周期的关键我们进去看看

  @NonNull
  private RequestManagerFragment getRequestManagerFragment(
      @NonNull final android.app.FragmentManager fm,
      @Nullable android.app.Fragment parentHint,
      boolean isParentVisible) {
    RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
    if (current == null) {
      current = pendingRequestManagerFragments.get(fm);
      if (current == null) {
        current = new RequestManagerFragment();
        current.setParentFragmentHint(parentHint);
        if (isParentVisible) {
          current.getGlideLifecycle().onStart();
        }
        pendingRequestManagerFragments.put(fm, current);
        fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
        handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
      }
    }
    return current;
  }

这个主要是把RequestManagerFragment通过事务管理添加到activity的FragmentManager里面进行绑定,这样activity的生命周期就可以被RequestManagerFragment感知到了,接着由于RequestManager实现LifecycleListener接口里面有onStart,onStop,onDestroy方法,我们把创建的RequestManager传入到RequestManagerFragment里面进行绑定,这样就串起来,activity调用onstart----》RequestManagerFragment.onstart---》FragmentManager.onstart---->RequestTracker开始从集合里面拿到request调用begin开始请求图片
activity调用onstop---》RequestManagerFragment.onstop--》FragmentManager.onstop---->RequestTracker里面将处于请求集合的request清除掉并添加到等待处理的集合里面

2 Glide队列请求如何处理的?

当我们load.into(iv);方法时,所有的请求都会被添加到一个叫RequestTracker的集合中,而且这个集合有两个
一个是运行时集合,一个是等待集合;
如果当前页面停止,onStop方法被调用,所有的运行中的请求都会停止,并且全部添加到等待集合中;
当开始运行时,又会把所有等待集合中的请求 放到运行中去!

3 怎么处理请求

1:当RequestManager调用requestTracker.runRequest的时候,
2: 所有的请求都会构建成一个SingleRequest,并且开始调用begin方法运行;
3:begin方法最终会调用engine.load方法
4:根据request构建EngineKey
5:根据EngineKey去活动缓存中获取数据
6:如果获取不到,去内存缓存中获取数据
7:如果获取不到,通过硬盘缓存的线程池去获取本地硬盘的数据
8:如果获取不到本地的,通过网络的线程池去获取网络的数据

相关文章

网友评论

      本文标题:Glide的源码分析

      本文链接:https://www.haomeiwen.com/subject/ysmstrtx.html