博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【源码阅读】Glide源码阅读之with方法(一)
阅读量:6548 次
发布时间:2019-06-24

本文共 7249 字,大约阅读时间需要 24 分钟。

前言

本篇基于4.8.0版本

  • 【源码阅读】Glide源码阅读之with方法(一)

大多数情况下,我们使用glide 就一句代码

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

但是这一句代码里面蕴含着成吨的代码!

with方法有以下几个重载方法

public static RequestManager with(@NonNull Context context) {    return getRetriever(context).get(context);  }  public static RequestManager with(@NonNull Activity activity) {    return getRetriever(activity).get(activity);  }  public static RequestManager with(@NonNull FragmentActivity activity) {    return getRetriever(activity).get(activity);  } public static RequestManager with(@NonNull Fragment fragment) {    return getRetriever(fragment.getActivity()).get(fragment);  }  public static RequestManager with(@NonNull android.app.Fragment fragment) {    return getRetriever(fragment.getActivity()).get(fragment);  }  public static RequestManager with(@NonNull View view) {    return getRetriever(view.getContext()).get(view);  }复制代码

其中,getRetriever返回的是个RequestManagerRetriever对象

private static RequestManagerRetriever getRetriever(@Nullable Context context) {    // Context could be null for other reasons (ie the user passes in null), but in practice it will    // only occur due to errors with the Fragment lifecycle.    Preconditions.checkNotNull(        context,        "You cannot start a load on a not yet attached View or a Fragment where getActivity() "            + "returns null (which usually occurs when getActivity() is called before the Fragment "            + "is attached or after the Fragment is destroyed).");    return Glide.get(context).getRequestManagerRetriever();  }复制代码

接着是RequestManagerRetriever.get方法,在传入ContextActivityFragmentActivityFragmentandroid.app.FragmentView几种情况略有不同,大致可以分为Application非Application

  • Application 它生命周期即应用程序的生命周期,如果应用程序关闭的话,Glide的加载也会同时终止。
@NonNull  private RequestManager getApplicationManager(@NonNull Context context) {    // Either an application context or we're on a background thread.    if (applicationManager == null) {      synchronized (this) {        if (applicationManager == null) {          // Normally pause/resume is taken care of by the fragment we add to the fragment or          // activity. However, in this case since the manager attached to the application will not          // receive lifecycle events, we must force the manager to start resumed using          // ApplicationLifecycle.          // TODO(b/27524013): Factor out this Glide.get() call.          Glide glide = Glide.get(context.getApplicationContext());          applicationManager =              factory.build(                  glide,                  new ApplicationLifecycle(),                  new EmptyRequestManagerTreeNode(),                  context.getApplicationContext());        }      }    }    return applicationManager;  }复制代码
  • 非Application 都是向当前Activity添加一个隐藏的Fragment,当Activity销毁时,该Fragment也会销毁,销毁时,Glide 就会取消本次加载。
public RequestManager get(@NonNull 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);  }复制代码

唯一有区别的是,FragmentActivityFragment使用的是SupportRequestManagerFragmentActivity使用的是RequestManagerFragmentSupportRequestManagerFragment继承的是v4包的,而RequestManagerFragment是继承android.app.Fragment

@NonNull  private SupportRequestManagerFragment getSupportRequestManagerFragment(      @NonNull final FragmentManager fm, @Nullable Fragment parentHint, boolean isParentVisible) {    SupportRequestManagerFragment current =        (SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);    if (current == null) {      current = pendingSupportRequestManagerFragments.get(fm);      if (current == null) {        current = new SupportRequestManagerFragment();        current.setParentFragmentHint(parentHint);        if (isParentVisible) {          current.getGlideLifecycle().onStart();        }        pendingSupportRequestManagerFragments.put(fm, current);        fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();        handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();      }    }    return current;  }复制代码
@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;  }复制代码

SupportRequestManagerFragment中部分代码

@Override  public void onAttach(Context context) {    super.onAttach(context);    try {      registerFragmentWithRoot(getActivity());    } catch (IllegalStateException e) {      // OnAttach can be called after the activity is destroyed, see #497.      if (Log.isLoggable(TAG, Log.WARN)) {        Log.w(TAG, "Unable to register fragment with root", e);      }    }  }  @Override  public void onDetach() {    super.onDetach();    parentFragmentHint = null;    unregisterFragmentWithRoot();  }  @Override  public void onStart() {    super.onStart();    lifecycle.onStart();  }  @Override  public void onStop() {    super.onStop();    lifecycle.onStop();  }  @Override  public void onDestroy() {    super.onDestroy();    lifecycle.onDestroy();    unregisterFragmentWithRoot();  }复制代码

ActivityFragmentLifecycle相关代码

@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();    }  }复制代码

总结:通过阅读源码,我们可以发现,Glide的生命周期取决于我们with方法传入的是Application 还是非Application ,所以,应该尽量使用非Application,避免造成内存泄漏。

你的认可,是我坚持更新博客的动力,如果觉得有用,就请点个赞,谢谢

转载于:https://juejin.im/post/5cb6ebcee51d456e747c5329

你可能感兴趣的文章
Linux命令之touch
查看>>
如何在VS2012中查看IL代码
查看>>
oracle sql优化to_date和to_char 的使用
查看>>
Java实现求最大公约数和最小公倍数
查看>>
正则表达式【其一】
查看>>
拦截器
查看>>
运维杂记(四):无法进入PE系统
查看>>
多区域 ospf
查看>>
linux 时间同步
查看>>
JavaScript学习----基础知识
查看>>
图像,大文件的mysql导入与读取存放到本地
查看>>
win8安装前的准备
查看>>
android SDK Manager 无法更新的解决办法
查看>>
初学Linux的心得
查看>>
【地图API】为何您的坐标不准?如何纠偏?
查看>>
电脑公司GHOST WIN7 SP1装机版2014.04(32位)
查看>>
Wi-Fi模块Demo(新手教程)图文详解模块使用教程
查看>>
尺规院-DevOps
查看>>
我的友情链接
查看>>
通过经典的实际例子来学习正则表达式
查看>>