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,并且在生命周期方法中,调用暴露的监听的对应方法,这样来达到对外暴露生命周期方法的目的,怎么样,是不是挺巧妙的

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容