前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Glide源码之生命周期实现Glide源码之生命周期实现

Glide源码之生命周期实现Glide源码之生命周期实现

作者头像
HelloJack
发布2021-11-24 13:31:59
3410
发布2021-11-24 13:31:59
举报
文章被收录于专栏:Jack的Android之旅Jack的Android之旅

Glide这个图片加载框架有个比较好的一点就是图片加载回根据Activity或Fragment生命周期的变化而变化,假如Activity或者Fragment销毁的时候,Glide会停止加载,以节省资源防止内存泄漏。至于Glide内部是怎么实现这个功能,这就是我们这一篇的内容。 首先,我们又来看一下Glide最基础的加载语句:

代码语言:javascript
复制
 Glide.with(this).load("url").into(imageview)

而实现生命周期的绑定最重要的语句就是Glide.with(this),在with()方法里会传入Activity或者Fragment的对象,以便进行绑定。with()方法代码如下(注:以Activity为例):

代码语言:javascript
复制
public static RequestManager with(@NonNull Activity activity) {
    return getRetriever(activity).get(activity);
  }

而with()方法里,与生命周期相关的就是get()方法,源码如下:

代码语言:javascript
复制
public RequestManager get(@NonNull Activity activity) {
    if (Util.isOnBackgroundThread()) {
      //假如是后台线程调用
      return get(activity.getApplicationContext());
    } else if (activity instanceof FragmentActivity) {
      return get((FragmentActivity) activity);
    } else {
      //上面的代码最终都会执行这个,所以这里是最重要的。
      assertNotDestroyed(activity);
      frameWaiter.registerSelf(activity);
      android.app.FragmentManager fm = activity.getFragmentManager();
      return fragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
    }
  }

上面的代码最终都会走最后一步,即获取FragmentManager,然后传给fragmentGet()方法,这个方法才是生成管理生命周期的关键:

代码语言:javascript
复制
private RequestManager fragmentGet(@NonNull Context context,
                                   @NonNull android.app.FragmentManager fm,
                                   @Nullable android.app.Fragment parentHint,
                                   boolean isParentVisible) {
    //创建RequestManagerFragment对象
    RequestManagerFragment current = getRequestManagerFragment(fm, parentHint);
    //获取请求管理类
    RequestManager requestManager = current.getRequestManager();
    if (requestManager == null) {
     //假如没有,就生产该对象
      Glide glide = Glide.get(context);
      requestManager =factory.build(glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
      if (isParentVisible) {
        requestManager.onStart();
      }
      current.setRequestManager(requestManager);
    }
    return requestManager;
}

private RequestManagerFragment getRequestManagerFragment(
      @NonNull final android.app.FragmentManager fm,
      @Nullable android.app.Fragment parentHint) {

    //从FragmentManager获取RequestManagerFragment看有没有
    RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
    if (current == null) {
     //FragmentManager没有RequestManagerFragment,再从Glide缓存拿
      current = pendingRequestManagerFragments.get(fm);
      if (current == null) {
        //假如也没有,就生产新的RequestManagerFragment对象
        current = new RequestManagerFragment();
        current.setParentFragmentHint(parentHint);
        //将新的对象保存起来
        pendingRequestManagerFragments.put(fm, current);
        fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
        handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
      }
    }
    return current;
  }

上面的注释表明的基本流程,其中第一步就是获取RequestManagerFragment对象,再看看getRequestManagerFragment()里面的方法,,也没什么特别就是获取RequestManagerFragment再保存起来,那RequestManagerFragment是什么呢,其实RequestManagerFragment就是一个Fragment,

代码语言:javascript
复制
public class RequestManagerFragment extends Fragment {
    
  //省略....    
    
  public RequestManagerFragment() {
    this(new ActivityFragmentLifecycle());
  }

  RequestManagerFragment(@NonNull ActivityFragmentLifecycle lifecycle) {
    this.lifecycle = lifecycle;
  }

  //省略....    
    
}

我们刚才传入的Activity,生成一个Fragment用来干嘛?其实RequestManagerFragment是一个空的fragment,没有布局和View操作,与Activity绑定,仅仅用来监听生命周期。

在RequestManagerFragment创建的时候会通过构造器创建ActivityFragmentLifecycle对象,他是生命周期的回调监听,实现了Lifecycle接口。

代码语言:javascript
复制
public interface Lifecycle {
  void addListener(@NonNull LifecycleListener listener);

  void removeListener(@NonNull LifecycleListener listener);
}


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负责实现注册和移除LifecycleListener接口,而ActivityFragmentLifecycle集成Lifecycle,同时还包含还包含onStart,onStop,onDestroy这三个方法,这三个方法是对应这个RequestManagerFragment也就是Frgament的onStart,onStop,onDestroy三个回调方法。当创建RequestManagerFragment结束后,当前页面加载的时候生命周期传递到RequestManagerFragment,就会执行对象的生命周期的方法,当执行onStart时候,调用ActivityFragmentLifecycle的onStart,当执行onStop时候,调用ActivityFragmentLifecycle的onStop由此类推。 不过还有一个问题,就是ActivityFragmentLifecycle的addListener是在哪里赋值的,当创建完RequestManagerFragment后,还会调

代码语言:javascript
复制
requestManager =factory.build(glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);

生产RequestManager,监听就在这个时候,源码如下:

代码语言:javascript
复制
private static final RequestManagerRetriever.RequestManagerFactory DEFAULT_FACTORY = new RequestManagerRetriever.RequestManagerFactory() {
    //对应这个上面的build方法
    @NonNull
    public RequestManager build(@NonNull Glide glide, @NonNull Lifecycle lifecycle, @NonNull RequestManagerTreeNode requestManagerTreeNode, @NonNull Context context) {
        return new RequestManager(glide, lifecycle, requestManagerTreeNode, context);
    }
};

//生产RequestManager对象    
public RequestManager(
      @NonNull Glide glide,
      @NonNull Lifecycle lifecycle,
      @NonNull RequestManagerTreeNode treeNode,
      @NonNull Context context) {
    this(
        glide,
        lifecycle,
        treeNode,
        new RequestTracker(),
        glide.getConnectivityMonitorFactory(),
        context);
  }
  
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()) {
      Util.postOnUiThread(addSelfToLifecycle);
    } else {
      lifecycle.addListener(this);
    }
    lifecycle.addListener(connectivityMonitor);

    //省略代码...
  
  }  

上面的current.getGlideLifecycle()参数,该参数就是ActivityFragmentLifecycle,然后调用ActivityFragmentLifecycle的addListener方法进行注册,这样ActivityFragmentLifecycle生命周期管理类执行对应生命周期的时候就会调用RequestManager中的对应方法。对应的onStart就会开启网络请求,和设置ImageView监听到ImageView的onStart方法,onStart方法就这样监听到了。

当调ActivityFragmentLifecycle的onStart,onStop,onDestroy方法就会回调RequestManager的onStart,onStop,onDestroy方法,如下代码:

代码语言:javascript
复制
 public class RequestManager implements LifecycleListener, ……{
 
      @Override
      public synchronized void onStart() {
        //发起请求
        resumeRequests();
        //View的Target回调
        targetTracker.onStart();
      }
 
      @Override
      public synchronized void onStop() {
        //暂停请求
        pauseRequests();
         //View的Target回调
        targetTracker.onStop();
      }
 
      @Override
      public synchronized void onDestroy() {
        销毁请求
        targetTracker.onDestroy();
        //View的Target回调
        for (Target<?> target : targetTracker.getAll()) {
          clear(target);
        }
        //清空回调信息
        targetTracker.clear();
        requestTracker.clearRequests();
        lifecycle.removeListener(this);
        lifecycle.removeListener(connectivityMonitor);
        mainHandler.removeCallbacks(addSelfToLifecycle);
        glide.unregisterRequestManager(this);
      }
    }

这样就实现了Glide的生命周期管理,管理了请求开发,暂停,销毁这三个状态,使得更加节省资源,防止内存泄漏。也就是这个的基本流程

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021/10/8 下,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档