Glide请求的管理

我们在使用Glide的时候,展示一张图片,只需这样一行代

Glide.with(Activity/Fragment/Context).load(url).into(imageView);

这行代码的字面意思挺好理解,传入当前的上下文,下载给定url的图片,然后将图片展示到传入的ImageView上。

既然是下载图片,就肯定是网络或者IO操作,那么肯定是开了一个线程去操作的。由此就有可能会出现一个问题,假如我们进入一个Activity,然后加载一个图片,在加载完成之前,我们退出当前的Activity,按理来说在退出前应该停止加载图片吧,不然可能会浪费多余的资源或者出现内存泄漏,但是我们并没有在生命周期中调用任何Glide的相关的其他方法,那么Glide肯定做了什么我们不知道东西。

看看它的具体是如何实现的。

从with方法开始看,发现它有几个重载的方法

public static RequestManager with(Context context) {
        RequestManagerRetriever retriever = RequestManagerRetriever.get();
        return retriever.get(context);
    }

   public static RequestManager with(Activity activity) {
        RequestManagerRetriever retriever = RequestManagerRetriever.get();
        return retriever.get(activity);
    }

   public static RequestManager with(FragmentActivity activity) {
        RequestManagerRetriever retriever = RequestManagerRetriever.get();
        return retriever.get(activity);
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public static RequestManager with(android.app.Fragment fragment) {
        RequestManagerRetriever retriever = RequestManagerRetriever.get();
        return retriever.get(fragment);
    }

   public static RequestManager with(Fragment fragment) {
        RequestManagerRetriever retriever = RequestManagerRetriever.get();
        return retriever.get(fragment);
    }

RequestManagerRetriever

可以看出RequestManagerRetriever是一个单例,然后调用他的get方法,获得一个RequestManger,感觉从字面意思好像能大概理解它们有什么作用。RequestManagerRetriever的get方法也有几个重载方法,看其中的几个,作用都差不多,但是如果传入的Application,会有些不同,简单点说就是请求的生命周期跟你传入的参数对应的组件的生命周期对应

 public RequestManager get(Fragment fragment) {
        if (fragment.getActivity() == null) {
            throw new IllegalArgumentException("You cannot start a load on a fragment before it is attached");
        }
        //如果当前不是在主线程上,就使用applicationContext作为参数
        if (Util.isOnBackgroundThread()) {
            return get(fragment.getActivity().getApplicationContext());
        } else {
            //当前的参数是Fragment,说明是在Fragment中加载图片,
            //获取到当前Fragment内部管理Fragment的FragmentManager
            FragmentManager fm = fragment.getChildFragmentManager();
            return supportFragmentGet(fragment.getActivity(), fm);
        }
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public RequestManager get(Activity activity) {
        if (Util.isOnBackgroundThread() || Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
            return get(activity.getApplicationContext());
        } else {
            assertNotDestroyed(activity);
            android.app.FragmentManager fm = activity.getFragmentManager();
            return fragmentGet(activity, fm);
        }
    }

    private RequestManager getApplicationManager(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.
                    applicationManager = new RequestManager(context.getApplicationContext(),
                            new ApplicationLifecycle(), new EmptyRequestManagerTreeNode());
                }
            }
        }

        return applicationManager;
    }

除了传入的是ApplicationContext参数的,其余的都会调用到fragmentGet方法

RequestManager fragmentGet(Context context, android.app.FragmentManager fm) {
        //获取或者创建管理请求的Fragment
        RequestManagerFragment current = getRequestManagerFragment(fm);
        //获取当前的请求管理者,如果为空就创建一个
        RequestManager requestManager = current.getRequestManager();
        if (requestManager == null) {
            //关注一下current.getLifecycle()这个参数,用于监听Fragment的生命周期
            requestManager = new RequestManager(context, current.getLifecycle(), current.getRequestManagerTreeNode());
            current.setRequestManager(requestManager);
        }
        return requestManager;
    }

RequestManager

1、它实现了LifecycleListener,LifecycleListener中有onStart、onStop、onDestroy方法;
2、RequestManager中有一个Lifecycle属性,它来自它其实是ActivityFragmentLifecycle,来源于RequestManagerFragment,用于监听RequestManagerFragment的生命周期;
3、ActivityFragmentLifecycle会将当期的LifecycleListener(RequestManager)保存起来,等RequestManagerFragment生命周期变化的时候回调RequestManager的onStart、onStop、onDestroy方法

public class RequestManager implements LifecycleListener {
    private final Context context;
    //用于监听Activity/Fragment的生命周期
    private final Lifecycle lifecycle;
    //Activity、Fragment里面会嵌套多层Fragment,所以会有多个RequestManager,通过它可以获取所以的requestManager
    private final RequestManagerTreeNode treeNode;
    //用于跟踪,取消和重新启动正在进行,已完成和失败的请求
    private final RequestTracker requestTracker;
    private final Glide glide;
    //请求设置相关
    private final OptionsApplier optionsApplier;
    private DefaultOptions options;

    RequestManager(Context context, final Lifecycle lifecycle, RequestManagerTreeNode treeNode,
            RequestTracker requestTracker, ConnectivityMonitorFactory factory) {
        this.context = context.getApplicationContext();
        this.lifecycle = lifecycle;
        this.treeNode = treeNode;
        this.requestTracker = requestTracker;
        this.glide = Glide.get(context);
        this.optionsApplier = new OptionsApplier();
        //网络连接变化监听
        ConnectivityMonitor connectivityMonitor = factory.build(context,
                new RequestManagerConnectivityListener(requestTracker));

        // If we're the application level request manager, we may be created on a background thread. In that case we
        // cannot risk synchronously pausing or resuming requests, so we hack around the issue by delaying adding
        // ourselves as a lifecycle listener by posting to the main thread. This should be entirely safe.
        if (Util.isOnBackgroundThread()) {
            new Handler(Looper.getMainLooper()).post(new Runnable() {
                @Override
                public void run() {
                    lifecycle.addListener(RequestManager.this);
                }
            });
        } else {
            //将当期的requestManager加入到生命周期管理ActivityFragmentLifecycle中,
            //当Fragment的生命周期变化是会执行ActivityFragmentLifecycle对应的方法,然后就会回调requestManager当前的onStart、onStop、onDestroy
            lifecycle.addListener(this);
        }
        lifecycle.addListener(connectivityMonitor);
    }
  @Override
    public void onStart() {
        // onStart might not be called because this object may be created after the fragment/activity's onStart method.
        resumeRequests();
    }

    /**
     * Lifecycle callback that unregisters for connectivity events (if the android.permission.ACCESS_NETWORK_STATE
     * permission is present) and pauses in progress loads.
     */
    @Override
    public void onStop() {
        pauseRequests();
    }

    /**
     * Lifecycle callback that cancels all in progress requests and clears and recycles resources for all completed
     * requests.
     */
    @Override
    public void onDestroy() {
        requestTracker.clearRequests();
    }

    public void resumeRequests() {
        Util.assertMainThread();
        requestTracker.resumeRequests();
    }
    public void pauseRequests() {
        Util.assertMainThread();
        requestTracker.pauseRequests();
    }

RequestTracker

用于跟踪,取消和重新启动正在进行,已完成和失败的请求
它保存了当前RequestManagerFragment中的所有具体请求对象Request,它有如下方法,从方法名就可以看出意思

addRequest
clearRequests
pauseRequests
removeRequest
restartRequests
resumeRequests
runRequest

总结

简单点说,Glide请求的管理其实就是
1、通过RequestManagerRetriever创建一个不可见的RequestManagerFragment与对应的一个RequestManager
2、RequestManagerFragment的生命周期通过ActivityFragmentLifecycle传递到RequestManager
3、RequestManager中的生命周期回调,RequestTracker执行具体的请求的开始、停止
源码阅读没必要一股脑的看这个流程,那样不太容易理解,我们可以从某一小块入手,我们可以从包名大概看出一些门道,大概理解其中代表什么功能,然后各个去看


image.png
image.png

你可能感兴趣的:(Glide请求的管理)