Glide源码分析(一) Glide的图片加载的生命周期

介绍Glide的图片加载的生命周期

在Glide中,图片的加载会跟随这Activity或者Fragment的生命周期进行相应的加载,停止等操作,本节我们通过源码来分析一下Glide是怎么做到这点的

用法

在我的GlideSample中的StartActivity类中

Glide.with(StartActivity.this).load(R.mipmap.pizza).into(mIvShow);

分析

// 使用的上下文Context,可以是Application,Activity,Fragment实例
Glide.with()

我们看到源码,这里传入的5种类型参数

with(Context context)  //  any Context
with(android.app.Activity)
with(android.app.Fragment)
with(android.support.v4.app.Fragment)
with(android.support.v4.app.FragmentActivity)

我们以with(android.support.v4.app.FragmentActivity)为例看下

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

接着看下retriever.get(activity)方法

    public RequestManager get(FragmentActivity activity) {
        if (Util.isOnBackgroundThread()) {
           // 不在主线程,返回一个ApplicationContext关联的RequestManager
            return get(activity.getApplicationContext());
        } else {
            // 重点在这里,我们返回一个Fragment相关的RequestManager
            assertNotDestroyed(activity);
            // 获取activity对应的FragmentManager,主要目的是和Activity结合,
            // 塞入一个空的fragment对象,用于暴露出生命周期方法,这个在后面会看到
            FragmentManager fm = activity.getSupportFragmentManager();
            return supportFragmentGet(activity, fm);
        }
    }

这里我们很明显的看到如果调用with()方法的时候不是在主线程,那么我们会返回一个和ApplicationContext关联的RequestManager

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;
    }

如果是在主线程操作,那么我们会返回一个Fragment相关的RequestManager,这里涉及到一个很精妙的用法,怎样将Activity的生命周期暴露出来与你的封装控件结合使用

    RequestManager supportFragmentGet(Context context, FragmentManager fm) {
        // 获取一个自定义的Fragment
        SupportRequestManagerFragment current = getSupportRequestManagerFragment(fm);
        RequestManager requestManager = current.getRequestManager();
        if (requestManager == null) {
            // 生成RequestManager对象,看看,这里暴露出了Lifecycle接口,LIfecycle实现类中是一个监听LifecycleListener
            requestManager = new RequestManager(context, current.getLifecycle(), current.getRequestManagerTreeNode());
            current.setRequestManager(requestManager);
        }
        return requestManager;
    }

SupportRequestManagerFragment中关联了一个Lifecycle接口的实现类ActivityFragmentLifecycle

    public SupportRequestManagerFragment() {
        this(new ActivityFragmentLifecycle());
    }

其中,ActivityFragmentLifecycle类对外提供了添加监听的方法

@Override
    public void addListener(LifecycleListener listener) {
        ......
    }

并且ActivityFragmentLifecycle类方法加入到了这个Fragment的生命周期中,如下所示

    @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中调用了监听中的对应的生命周期方法

    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();
        }
    }

看到没,只要添加了监听实现类,就能获取到对应的生命周期,从而对外提供了生命周期方法

总结

看过源代码,给我一个什么启示,由于Fragment在onAttach()之后,与Activity有相同的生命周期,那么我们就可以通过给Activity添加一个不显示界面的fragment,并且在生命周期方法中,调用暴露的监听的对应方法,这样来达到对外暴露生命周期方法的目的,怎么样,是不是挺巧妙的

好了,这里就先讲解到这里了,后面我们会继续根据介绍暴露出来的接口,怎么跟图片加载结合在一起