Glide源码分析其二:生命周期管理

欢迎收看:Glide源码分析其一:基本流程

Glide****的生命周期的实现主要是通过创建一个****Fragment进行实现的

在****Glide.with(context)****这段代码中****Glide****会创建一个****RequestManager****类。该类是实现生命周期的关键方法

public class RequestManager implements LifecycleListener {
    private final Context context;
    private final Lifecycle lifecycle;
    private final RequestManagerTreeNode treeNode;
    private final RequestTracker requestTracker;
    private final Glide glide;
    private final OptionsApplier optionsApplier;
    private DefaultOptions options;

下面是获取RequestManager的方法:

RequestManager supportFragmentGet(Context context, FragmentManager fm) {
        SupportRequestManagerFragment current = getSupportRequestManagerFragment(fm);
        RequestManager requestManager = current.getRequestManager();
        if (requestManager == null) {
            requestManager = new RequestManager(context, current.getLifecycle(), current.getRequestManagerTreeNode());
            current.setRequestManager(requestManager);
        }
        return requestManager;
    }

其中创建一个了一个SupportRequestManagerFragment的对象,我们来看这个类:

public class RequestManagerFragment extends Fragment {
    private final ActivityFragmentLifecycle lifecycle;
    private final RequestManagerTreeNode requestManagerTreeNode = new FragmentRequestManagerTreeNode();
    private RequestManager requestManager;
    private final HashSet<RequestManagerFragment> childRequestManagerFragments
        = new HashSet<RequestManagerFragment>();
    private RequestManagerFragment rootRequestManagerFragment;

其中的ActivityFragmentLifecycle实现了Lifecycle,根据Lifecycle的注释:

A {@link com.bumptech.glide.manager.Lifecycle} implementation for tracking and notifying listeners of {@link android.app.Fragment} and {@link android.app.Activity} lifecycle events.

可知,这个接口用于实现Activity或者Fragment的生命周期的回调

RequestManagerFragment

onAttach()

 @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        rootRequestManagerFragment = RequestManagerRetriever.get()
                .getRequestManagerFragment(getActivity().getFragmentManager());
        if (rootRequestManagerFragment != this) {
            rootRequestManagerFragment.addChildRequestManagerFragment(this);
        }
    }

先获取到root,如果当前获取的root不等于当前的管理的Fragment,则添加到当前管理类中的一个set结合中(实际上,RequestManagerFragment既充当了一个Fragment来组织生命周期的回调,同样也是一个管理者的角色,他管理了依附于不同fragmentActivty和Activity的fragment)。

那么当该fragment在销毁的时候,会执行到onDetach()放方法,直接将自己销毁:

@Override
    public void onDetach() {
        super.onDetach();
        if (rootRequestManagerFragment != null) {
            rootRequestManagerFragment.removeChildRequestManagerFragment(this);
            rootRequestManagerFragment = null;
        }
    }

值得注意的是,Glide会在actiivty进行重新创建的时候,可能因为内存不够而无法创建时,回调onLowMemory:

 @Override
    public void onLowMemory() {
        super.onLowMemory();
        // If an activity is re-created, onLowMemory may be called before a manager is ever set.
        // See #329.
        if (requestManager != null) {
            requestManager.onLowMemory();
        }
    }

lifecycle的注入

 SupportRequestManagerFragment getSupportRequestManagerFragment(final FragmentManager fm) {
       SupportRequestManagerFragment current = (SupportRequestManagerFragment) fm.findFragmentByTag(
           FRAGMENT_TAG);
       if (current == null) {
           current = pendingSupportRequestManagerFragments.get(fm);
           if (current == null) {
               current = new SupportRequestManagerFragment();
               pendingSupportRequestManagerFragments.put(fm, current);
               fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
               handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
           }
       }
       return current;
   }

我们知道,在每次创建SupportRequestManagerFragment的时候,均需要一个fm作为参数,而该fm会根据一个TAG获取fragment,这样,不同的activity中的Imageview在创Glide请求的时候,会创建不同的SupportRequestManagerFragment对象,并且,我们看到SupportRequestManagerFragment的构造方法:

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

    // For testing only.
    @SuppressLint("ValidFragment")
    public SupportRequestManagerFragment(ActivityFragmentLifecycle lifecycle) {
        this.lifecycle = lifecycle;
    }

可以看见,每个不用的activity中创建的fragment会拥有自己的生命周期。

接下来,我们看上面RequestManagerFragment中的其他的生命周期的回调是在何种时候进行回调的。

1、经过前文的分析,我们知道,Glide.with(context)会创建一个RequestManager对象,该对象

requestManager = new RequestManager(context, current.getLifecycle(), current.getRequestManagerTreeNode());

中已经set进去了管理生命周期的RequestManagerfragment的lifecycle的对象。

2、那么我们就继续朝着api的调用方向:load(string)继续向下看

 public DrawableTypeRequest<String> load(String string) {
        return (DrawableTypeRequest<String>) fromString().load(string);
    }

首先创建一个DrawableTypeRequest对象,该对象,会被RequestManager注入Lifecycle:

return optionsApplier.apply(
                new DrawableTypeRequest<T>(modelClass, streamModelLoader, fileDescriptorModelLoader, context,
                        glide, requestTracker, lifecycle, optionsApplier));

这里很厉害的一个地方就是:optionsApplier.apply会把optionsApplier自己注入进去,这样,

public <Y extends Target<TranscodeType>> Y into(Y target) {

        ...
        
        Request request = buildRequest(target);
        
        /** setTag **/
        target.setRequest(request);
        lifecycle.addListener(target);
        requestTracker.runRequest(request);

        return target;
    }

中的lifecycle即为上面requestManager传递过去。

3、RequestTracker
该类是真正起到保证fragment的生命周期和进行图片资源请求的生命周期的桥梁。

RequestManager中的其他生命周期代码可知:

  • onStart()
    /**
     * Lifecycle callback that registers for connectivity events (if the android.permission.ACCESS_NETWORK_STATE
     * permission is present) and restarts failed or paused requests.
     */
    @Override
    public void onStart() {
        // onStart might not be called because this object may be created after the fragment/activity's onStart method.
        resumeRequests();
    }

其中追踪resumeRequests()是:

/**
     * Restarts any loads that have not yet completed.
     *
     * @see #isPaused()
     * @see #pauseRequests()
     */
    public void resumeRequests() {
        Util.assertMainThread();
        requestTracker.resumeRequests();
    }

最终的执行者是requestTracker,调用该段代码会将

 isPaused = false;

这样,在接下来的进行请求或者重新请求时,会依据这个标志位进行判断。

其他的生命周期也是这样子的,就不一一说了。

****最后,说明如何进行参数****requestTracker的传递的

即为上面:

创建一个DrawableTypeRequest对象,该对象,会被RequestManager注入Lifecycle,

return optionsApplier.apply(
                new DrawableTypeRequest<T>(modelClass, streamModelLoader, fileDescriptorModelLoader, context,
                        glide, requestTracker, lifecycle, optionsApplier));

同时,requestTracker也会被传入进去,这样,所有的都已经串通了,Glide的生命周期就是这样了。

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

推荐阅读更多精彩内容

  • 本文是Glide源码解析系列的第一篇,通过这篇文档,将可以了解到: 1.Glide如何绑定Activity、Fra...
    他的大姨父阅读 8,526评论 6 42
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,569评论 25 707
  • 声明 本文章是基于 glide 3.6.1的 个各类的功能介绍 1.Glide:向外暴露单例静态接口,构建Requ...
    河里的枇杷树阅读 1,143评论 0 3
  • 一把折扇的赏析 1.折扇正面为高逸图,纸质为洒金宣扇面,底纹为罗纹,有漏矾现象,小山溪流旁,梅枝折,琴方罢,高士独...
    晓月华梦阅读 560评论 8 13
  • 穷人和富人之间到底有什么差别呢?从表面上看,穷人和富人的差距是钱多钱少的问题,而实质呢?是穷人和富人对待理财的态度...
    财商实践传播者阅读 264评论 0 0