/** * Begin a load with Glide by passing in a context. * * @param context Any context, will not be retained. * @see #with(android.app.Activity) * @see #with(android.app.Fragment) * @see #with(androidx.fragment.app.Fragment) * @see #with(androidx.fragment.app.FragmentActivity) */@NonNullpublic static RequestManager with(@NonNull Context context) {    return getRetriever(context).get(context);}@NonNullpublic static RequestManager with(@NonNull Activity activity) {    return getRetriever(activity).get(activity);}@NonNullpublic static RequestManager with(@NonNull FragmentActivity activity) {    return getRetriever(activity).get(activity);}@NonNullpublic static RequestManager with(@NonNull Fragment fragment) {    return getRetriever(fragment.getContext()).get(fragment);}@SuppressWarnings("deprecation")@Deprecated@NonNullpublic static RequestManager with(@NonNull android.app.Fragment fragment) {    return getRetriever(fragment.getActivity()).get(fragment);}@NonNullpublic static RequestManager with(@NonNull View view) {    return getRetriever(view.getContext()).get(view);}

可以看到,with()方法的重载种类非常多,既可以传入Activity,也可以传入Fragment或者是Context。每一个with()方法重载的代码都非常简单,都是先调用getRetriever方法得到一个RequestManagerRetriever对象,然后再调用RequestManagerRetriever的实例get()方法,去获取RequestManager对象。

RequestManagerRetriever类中
Glide的with()方法和生命周期的源码分析_第1张图片

    @NonNull    public RequestManager get(@NonNull Context context) {        if (context == null) {            throw new IllegalArgumentException("You cannot start a load on a null Context");        }         == 如果不是Application 并且是在主线程的情况==        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                    && ((ContextWrapper) context).getBaseContext().getApplicationContext() != null) {                return get(((ContextWrapper) context).getBaseContext());            }        }        == Application 或者是在非主线程的情况 ==        return getApplicationManager(context);    }    @NonNull    public RequestManager get(@NonNull FragmentActivity activity) {        if (Util.isOnBackgroundThread()) {            return get(activity.getApplicationContext());        } else {            assertNotDestroyed(activity);            FragmentManager fm = activity.getSupportFragmentManager();            return supportFragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));        }    }    @NonNull    public RequestManager get(@NonNull Fragment fragment) {        Preconditions.checkNotNull(                fragment.getContext(),                "You cannot start a load on a fragment before it is attached or after it is destroyed");        if (Util.isOnBackgroundThread()) {            return get(fragment.getContext().getApplicationContext());        } else {            FragmentManager fm = fragment.getChildFragmentManager();            return supportFragmentGet(fragment.getContext(), fm, fragment, fragment.isVisible());        }    }    @SuppressWarnings("deprecation")    @Deprecated    @NonNull    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)    public RequestManager get(@NonNull android.app.Fragment fragment) {        if (fragment.getActivity() == null) {            throw new IllegalArgumentException(                    "You cannot start a load on a fragment before it is attached");        }        if (Util.isOnBackgroundThread() || Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {            return get(fragment.getActivity().getApplicationContext());        } else {            android.app.FragmentManager fm = fragment.getChildFragmentManager();            return fragmentGet(fragment.getActivity(), fm, fragment, fragment.isVisible());        }    }    @SuppressWarnings("deprecation")    @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));        }    }    @SuppressWarnings("deprecation")    @NonNull    public RequestManager get(@NonNull View view) {        if (Util.isOnBackgroundThread()) {            return get(view.getContext().getApplicationContext());        }        Preconditions.checkNotNull(view);        Preconditions.checkNotNull(                view.getContext(), "Unable to obtain a request manager for a view without a Context");        Activity activity = findActivity(view.getContext());        // The view might be somewhere else, like a service.        if (activity == null) {            return get(view.getContext().getApplicationContext());        }        if (activity instanceof FragmentActivity) {            Fragment fragment = findSupportFragment(view, (FragmentActivity) activity);            return fragment != null ? get(fragment) : get((FragmentActivity) activity);        }        android.app.Fragment fragment = findFragment(view, activity);        if (fragment == null) {            return get(activity);        }        return get(fragment);    }

上述代码虽然看上去逻辑有点复杂,但是将它们梳理清楚后还是很简单的。RequestManagerRetriever类中看似有很多个get()方法的重载,什么Context参数,Activity参数,Fragment参数等等,实际上只有两种情况而已,即传入Application类型的参数,和传入非Application类型的参数。

如果我们是在非主线程当中使用的Glide,那么不管你是传入的Activity还是Fragment,都会被强制当成Application来处理。 if (Util.isOnBackgroundThread()) {    return get(activity.getApplicationContext()); } 

我们先来看传入Application参数的情况。如果在Glide.with()方法中传入的是一个Application对象,那么这里就会调用带有Context参数的get()方法重载,然后会调用getApplicationManager()方法来获取一个RequestManager对象。其实这是最简单的一种情况,因为Application对象的生命周期即应用程序的生命周期,因此Glide并不需要做什么特殊的处理,它自动就是和应用程序的生命周期是同步的,如果应用程序关闭的话,Glide的加载也会同时终止。

接下来我们看传入非Application参数的情况。不管你在Glide.with()方法中传入的是Activity、FragmentActivity、v4包下的Fragment、还是app包下的Fragment,最终的流程都是一样的,那就是会向当前的Activity当中添加一个隐藏的Fragment。

那么这里为什么要添加一个隐藏的Fragment呢?因为Glide需要知道加载的生命周期。很简单的一个道理,如果你在某个Activity上正在加载着一张图片,结果图片还没加载出来,Activity就被用户关掉了,那么图片还应该继续加载吗?当然不应该。可是Glide并没有办法知道Activity的生命周期,于是Glide就使用了添加隐藏Fragment的这种小技巧,因为Fragment的生命周期和Activity是同步的,如果Activity被销毁了,Fragment是可以监听到的,这样Glide就可以捕获这个事件并停止图片加载了

分别对应的v4包和APP包下的两种Fragment的情况。supportFragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity))fragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity))

分析v4包下的,注释在代码中

  @NonNull  public RequestManager get(@NonNull FragmentActivity activity) {    if (Util.isOnBackgroundThread()) {      return get(activity.getApplicationContext());    } else {    //这里是保证当前的FragmentActivity  或者是v4fragment attah 的FragmentActivity没有被销毁      assertNotDestroyed(activity);      FragmentManager fm = activity.getSupportFragmentManager();      // 创建一个无ui的fragment      return supportFragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));    }  }

supportFragmentGet方法中创建fragment的方法

    SupportRequestManagerFragment current =        getSupportRequestManagerFragment(fm, parentHint, isParentVisible);          == 这里的创建逻辑 首先通过tag来寻找是否创建过该fragment,如果没有的话,在    Map<FragmentManager,SupportRequestManagerFragment>pendingSupportRequestManagerFragments   中查询是否保存过,如果没有的话则创建一个无ui的fragment,并且保存到map中,并且如果acticity是  visible状态,则注册current.getGlideLifecycle().onStart(),然后在通过handler发送消息,将map  中的该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;  }
我们发现在创建fragment的时候会在构造方法中创建ActivityFragmentLifecycle 对象public class SupportRequestManagerFragment extends Fragment {    private final ActivityFragmentLifecycle lifecycle;    public SupportRequestManagerFragment() {        this(new ActivityFragmentLifecycle());    }    @VisibleForTesting    @SuppressLint("ValidFragment")    public SupportRequestManagerFragment(@NonNull ActivityFragmentLifecycle lifecycle) {        this.lifecycle = lifecycle;    }    @NonNull    ActivityFragmentLifecycle getGlideLifecycle() {        return lifecycle;    }    @Override    public void onStart() {        super.onStart();        lifecycle.onStart();    }    @Override    public void onStop() {        super.onStop();        lifecycle.onStop();    }    @Override    public void onDestroy() {        super.onDestroy();        lifecycle.onDestroy();    }}
ActivityFragmentLifecycle类是生命周期回调的管理类,它实现了LifeCycle接口,会将LifecycleListener的接口加入到ActivityFragmentLifecycle类中的Set集合中,当SupportRequestManagerFragment的生命周期的方法触发时,会调用ActivityFragmentLifeCycle的相应方法。主要保存了isStarted和isDestroyed变量,并提供了addListener和removeListener方法,如果想获取到生命周期的回调,只需调用addListener()方法注册即可。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();        }    }}

更多相关文章

  1. Android Http请求失败解决方法
  2. android TelephonyManager类的方法
  3. Android OKhttp 上传文件袋参数
  4. android更新UI的几种方法
  5. android 调用 Menu 两种方法
  6. ANDROID NDK使用第三方静态库的方法
  7. Android 应用退出的几种方法

随机推荐

  1. 坑爹啊 横向滑动多屏竟然官方就有
  2. Android 获取唯一硬件编号
  3. android studio
  4. Android(安卓)使用Glide加载图片
  5. Android 问题记录
  6. 【Android】安卓运行问题
  7. Android’s HTTP Clients(Android的HTTP客
  8. 配置Android在MyEclipse下的开发环境
  9. android典型代码系列(四)------android全
  10. android studio关于targetSdk version,min