/** * 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类中

    @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中利用Intent传递数据到另一个页面
  2. android更新UI的几种方法
  3. android TelephonyManager类的方法
  4. Android方法的传递值及其改变
  5. android中的定时器
  6. 【Android】播放视频的简易播放器源码
  7. Android(安卓)Http请求失败解决方法
  8. 浅谈Java中Collections.sort对List排序的两种方法
  9. Python list sort方法的具体使用

随机推荐

  1. [置顶] 我的Android进阶之旅------>Andro
  2. Android 国际化工具 Android Localizer
  3. 【Android】Android 博客园客户端 (七)登录
  4. android——json解析
  5. HTC Kaiser 编译Android Kernel zImage
  6. android中ProgressDialog与ProgressBar的
  7. Android 换肤
  8. Scala&Android下的开发trait经验分享
  9. unity安卓多个sdk合并
  10. Android(安卓)4.2 BT系统之蓝牙关闭过程