美文网首页
Glide的with()过程和Glide的生命周期的源码分析

Glide的with()过程和Glide的生命周期的源码分析

作者: 长远勿见 | 来源:发表于2018-09-27 22:19 被阅读0次

      在Android开发中,或多或少你都会使用过很多的框架,但是没有一个框架会像Glide一样好用。Glide.with(context).load(url).into(imageView).一行代码解决了很多问题,今天我们就来深入Glide的源码,来看看这一行代码背后的故事。先从Glide的with()方法开始我们的探索。

    with()过程分析

    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);
        }
    public static RequestManager with(android.app.Fragment fragment) {
            RequestManagerRetriever retriever = RequestManagerRetriever.get();
            return retriever.get(fragment);
        }
    /**
         * Begin a load with Glide that will be tied to the given {@link android.support.v4.app.Fragment}'s lifecycle and
         * that uses the given {@link android.support.v4.app.Fragment}'s default options.
         *
         * @param fragment The fragment to use.
         * @return A RequestManager for the given Fragment that can be used to start a load.
         */
    public static RequestManager with(Fragment fragment) {
            RequestManagerRetriever retriever = RequestManagerRetriever.get();
            return retriever.get(fragment);
        }
    

      Glide类里面有很多with()方法的重载,在with()方法中传入不同类型的参数,来调用不同的重载的with()方法。可以看到,Glide为
    Activity和Fragment(android.app.Fragment和v4包下的Fragment)都提供Glide的使用。
      通过看Glide的这几个with()方法,可以发现里面都调用了RequestManageRetriever类的get()方法。

    • RequestManagerRetriever类:帮助拿到RequestManager对象,
      RequestManageRetriever类里面的get()方法
    private static final RequestManagerRetriever INSTANCE = new RequestManagerRetriever();
    public static RequestManagerRetriever get() {
            return INSTANCE;
        }
    

      这个RequestManagerRetriever类里面的get()方法是一个static的静态内部方法,返回一个静态RequestManagerRetriever对象,这是一个单例实现。
      在Glide类的这几个重载的with()方法中,首先都是先得到了RequestManagerRetriever对象,紧接着都调用了RequestManagerRetriever对象的带参数的实例get()方法,只不过不同的with()方法中传入RequestManagerRetriever类的get()方法的参数类型不同罢了。

    RequestManagerRetriever类中

    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;
        }
    public RequestManager get(Context context) {
            if (context == null) {
                throw new IllegalArgumentException("You cannot start a load on a null Context");
            } 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) {
                    return get(((ContextWrapper) context).getBaseContext());
                }
            }
    
            return getApplicationManager(context);
        }
    public RequestManager get(FragmentActivity activity) {
            if (Util.isOnBackgroundThread()) {
                return get(activity.getApplicationContext());
            } else {
                assertNotDestroyed(activity);
                FragmentManager fm = activity.getSupportFragmentManager();
                return supportFragmentGet(activity, fm);
            }
        }
    public RequestManager get(Fragment fragment) {
            if (fragment.getActivity() == null) {
                throw new IllegalArgumentException("You cannot start a load on a fragment before it is attached");
            }
            if (Util.isOnBackgroundThread()) {
                return get(fragment.getActivity().getApplicationContext());
            } else {
                FragmentManager fm = fragment.getChildFragmentManager();
                return supportFragmentGet(fragment.getActivity(), fm);
            }
        }
    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);
            }
        }
     public RequestManager get(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);
            }
        }
    

      可以看到在RequestManagerRetriever类中,有很多get()实例方法的重载,归根结底的分为传入Application类型的和非Application类型的参数。
    传入Application类型的参数时,就会调用getApplicationManager()方法。在这个方法中会生成RequestManager对象并返回,这个RequestManager对象就是Glide类的with()方法中所返回的。
    传入非Application类型的参数时,会根据传入的是Activity,还是Fragment(android.app.Fragment和v4包下的Fragment)来调用不同的get()方法。这些get()方法中传入的参数类型不一样,但是这些get()方法中的大致处理流程是一致的。我们选一个传入v4包下的Fragment类型的get()方法来看。

    传入v4包下的Fragment到RequestManagerRetriever的实例get()方法

    static final String FRAGMENT_TAG = "com.bumptech.glide.manager";
    final Map<android.app.FragmentManager, RequestManagerFragment> pendingRequestManagerFragments =
                new HashMap<android.app.FragmentManager, RequestManagerFragment>();
    private final Handler handler;
    public RequestManager get(Fragment fragment) {
            if (fragment.getActivity() == null) {
                throw new IllegalArgumentException("You cannot start a load on a fragment before it is attached");
            }
            //不在主线程中
            if (Util.isOnBackgroundThread()) {
              //调用Application类型参数的get()方法
                return get(fragment.getActivity().getApplicationContext());
            } else {
                //管理Fragment的FragmentManager
                FragmentManager fm = fragment.getChildFragmentManager();
                return supportFragmentGet(fragment.getActivity(), fm);
            }
        }
    RequestManager supportFragmentGet(Context context, FragmentManager fm) {
           // SupportRequestManagerFragment是一个无UI的Fragment
            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 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;
        }
     public boolean handleMessage(Message message) {
            boolean handled = true;
            Object removed = null;
            Object key = null;
            switch (message.what) {
                case ID_REMOVE_FRAGMENT_MANAGER:
                    android.app.FragmentManager fm = (android.app.FragmentManager) message.obj;
                    key = fm;
                    removed = pendingRequestManagerFragments.remove(fm);
                    break;
                case ID_REMOVE_SUPPORT_FRAGMENT_MANAGER:
                    FragmentManager supportFm = (FragmentManager) message.obj;
                    key = supportFm;
                    removed = pendingSupportRequestManagerFragments.remove(supportFm);
                    break;
                default:
                    handled = false;
            }
            if (handled && removed == null && Log.isLoggable(TAG, Log.WARN)) {
                Log.w(TAG, "Failed to remove expected request manager fragment, manager: " + key);
            }
            return handled;
        }
    
    • SupportRequestManagerFragment:是一个无UI的虚拟的Fragment,它是来辅助Glide来进行生命周期管理的。因为当使用Glide加载图片时,Glide不会感知到Activity的销毁。通过这个虚拟的Fragment来感知到Activity的生命周期,并作出及时的反应。
    • RequestManagerFragment与SupportRequestManagerFragment一样,都是虚拟的Fragment,只不过前者是android.app.Fragment包下的Fragment,后者是v4包下的Fragment。

      分析一下这个过程,在RequestManagerRetriever类的get(Fragment fragment)方法中,先是进行判断,不在主线程中就会调用调用Application类型参数的get()方法,否则生成一个管理Fragment的FragmentManager,然后调用supportFragmentGet()并将生成的FragmentManager对象传入。
      在supportFragmentGet()方法中,先是调用了getSupportRequestManagerFragment()方法;那先进入这个方法中,在这个方法中,先是通过fm.findFragmentByTag( FRAGMENT_TAG)来寻找是否已经存在这个SupportRequestManagerFragment,如果存在就直接返回。否则生成SupportRequestManagerFragment对象,并以FragmentManager为key,SupportRequestManagerFragment对象为value存入pendingRequestManagerFragments中,这个pendingRequestManagerFragments是一个HashMap。接着将刚刚生成的Fragment加入事物管理器中,但是紧接着又调用handel发送了一条消息,我们进入handleMessage()方法中,可以发现它将刚刚加入HashMap的Fragment又删除了。
      怎么回事?刚刚加入进去,怎么紧接着又给删除了。
      来分析一下这个过程。
      首先在Fragment和Activity绑定时,是通过开启事务的方式来进行绑定的,也就是通过Hander来处理的。(感兴趣这个过程的话可以通过看源码来发现)

    Glide.with(context).load(url).into(image1);
    Glide.with(context).load(url).into(image2);
    

      我们看上面的两行代码,在同一个Activity中分别为两个ImageView加载图片。
      当第一行代码运行到getSupportRequestManagerFragment()方法时,由于之前没有SupportRequestManagerFragment实例,这个时候会生成一个新的SupportRequestManagerFragment实例,并保存在HashMap中,生成新的SupportRequestManagerFragment实例时,就会发Fragment于Activity的绑定,Handler会发送消息来进行绑定,假设这个消息为m1,紧接着在getSupportRequestManagerFragment()方法中,就会使用Handler来发送从HashMap中删除保存的SupportRequestManagerFragment实例对象的消息,假设这个消息为m2。
      在Handler处理消息时,如果在m1与m2消息之前,Handler的消息队列中还存在其他的消息,此时m1与m2还没有得到处理,就是此时还没有进行Fragment与Activity的绑定。第二行Glide.with(context).load(url).into(image2);代码已经进行到了getSupportRequestManagerFragment()方法了,如果此时我们不将Fragment存入HashMap中,就会重新生成一个SupportRequestManagerFragment,这是Glide所不允许的,每一个Activity或者Fragment在使用Glide时,只能有一个所依附的虚拟的Fragment。所以将之前所生成的SupportRequestManagerFragment存储到HashMap中,这样就不会重复生成SupportRequestManagerFragment,等到SupportRequestManagerFragment与Activity绑定完成后,也就是消息m1处理完成后,再将SupportRequestManagerFragment从HashMap中销毁。
      这个过程分析完了,之后在getSupportRequestManagerFragment()方法中将Fragment返回,接着回到supportFragmentGet()方法中。在这个方法中,接着就生成了RequestManager对象。注意到,在生成这个RequestManager对象时构造器中传入的是刚刚从getSupportRequestManagerFragment()方法中返回的SupportRequestManagerFragment对象中的一些东西。
      Glide的with()过程分析完了,最终得到了Gilde类的with()方法中需要的RequsetManager对象。

    Glide的生命周期

      从SupportRequestManagerFragment类开始吧。
      来看一下SupportRequestManagerFragment类。

    SupportRequestManagerFragment类

    private final ActivityFragmentLifecycle lifecycle;
    //在SupportRequestManagerFragment类的构造方法中生成ActivityFragmentLifecycle对象
    public SupportRequestManagerFragment() {
            this(new ActivityFragmentLifecycle());
        }
    public SupportRequestManagerFragment(ActivityFragmentLifecycle lifecycle) {
            this.lifecycle = lifecycle;
        }
    
    • ActivityFragmentLifecycle类是生命周期回调的管理类,它实现了LifeCycle接口,会将LifecycleListener的接口加入到ActivityFragmentLifecycle类中的Set集合中,当SupportRequestManagerFragment的生命周期的方法触发时,会调用ActivityFragmentLifeCycle的相应方法。

    ActivityFragmentLifeCycle的相应方法

    private final Set<LifecycleListener> lifecycleListeners =
                Collections.newSetFromMap(new WeakHashMap<LifecycleListener, Boolean>());
    private boolean isStarted;
    private boolean isDestroyed;
    @Override
        public void addListener(LifecycleListener listener) {
            lifecycleListeners.add(listener);
    
            if (isDestroyed) {
                listener.onDestroy();
            } else if (isStarted) {
                listener.onStart();
            } else {
                listener.onStop();
            }
        }
    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();
            }
        }
    

    SupportRequestManagerFragment类中

    @Override
        public void onStart() {
            super.onStart();
            lifecycle.onStart();
        }
    
        @Override
        public void onStop() {
            super.onStop();
            lifecycle.onStop();
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            lifecycle.onDestroy();
        }
    

      可以看到当SupportRequestManagerFragment类中的相应的生命周期的方法调用时就会调用ActivityFragmentLifeCycle的相应方法。
      继续SupportRequestManagerFragment类。

    SupportRequestManagerFragment类中

    private final RequestManagerTreeNode requestManagerTreeNode =
                new SupportFragmentRequestManagerTreeNode();
    private final HashSet<SupportRequestManagerFragment> childRequestManagerFragments =
            new HashSet<SupportRequestManagerFragment>();
    private SupportRequestManagerFragment rootRequestManagerFragment;
    @Override
        public void onAttach(Activity activity) {
            super.onAttach(activity);
            rootRequestManagerFragment = RequestManagerRetriever.get()
                    .getSupportRequestManagerFragment(getActivity().getSupportFragmentManager());
            if (rootRequestManagerFragment != this) {
                rootRequestManagerFragment.addChildRequestManagerFragment(this);
            }
        }
    
        @Override
        public void onDetach() {
            super.onDetach();
            if (rootRequestManagerFragment != null) {
                rootRequestManagerFragment.removeChildRequestManagerFragment(this);
                rootRequestManagerFragment = null;
            }
        }
    
     private void addChildRequestManagerFragment(SupportRequestManagerFragment child) {
            childRequestManagerFragments.add(child);
        }
    
        private void removeChildRequestManagerFragment(SupportRequestManagerFragment child) {
            childRequestManagerFragments.remove(child);
        }
    
     public Set<SupportRequestManagerFragment> getDescendantRequestManagerFragments() {
            if (rootRequestManagerFragment == null) {
                return Collections.emptySet();
            } else if (rootRequestManagerFragment == this) {
                return Collections.unmodifiableSet(childRequestManagerFragments);
            } else {
                HashSet<SupportRequestManagerFragment> descendants =
                    new HashSet<SupportRequestManagerFragment>();
                for (SupportRequestManagerFragment fragment
                    : rootRequestManagerFragment.getDescendantRequestManagerFragments()) {
                    if (isDescendant(fragment.getParentFragment())) {
                        descendants.add(fragment);
                    }
                }
                return Collections.unmodifiableSet(descendants);
            }
        }
    
    private boolean isDescendant(Fragment fragment) {
            Fragment root = this.getParentFragment();
            while (fragment.getParentFragment() != null) {
                if (fragment.getParentFragment() == root) {
                    return true;
                }
                fragment = fragment.getParentFragment();
            }
            return false;
        }
    
    private class SupportFragmentRequestManagerTreeNode implements RequestManagerTreeNode {
            @Override
            public Set<RequestManager> getDescendants() {
                Set<SupportRequestManagerFragment> descendantFragments = getDescendantRequestManagerFragments();
                HashSet<RequestManager> descendants = new HashSet<RequestManager>(descendantFragments.size());
                for (SupportRequestManagerFragment fragment : descendantFragments) {
                    if (fragment.getRequestManager() != null) {
                        descendants.add(fragment.getRequestManager());
                    }
                }
                return descendants;
            }
        }
    

      在SupportRequestManagerFragment刚刚和Activity建立连接的时候即在onAttach()方法中,会初始化rootRequestManagerFragment实例变量。

      rootRequestManagerFragment = RequestManagerRetriever.get()
                    .getSupportRequestManagerFragment(getActivity().getSupportFragmentManager());
    

      注意这个初始化的过程,在getSupportRequestManagerFragment()方法中传入的是getActivity().getSupportFragmentManager()

    • 如果在Glide.with()时传入的是Activity类型的参数,则会得到Activity的SupportRequestManagerFragment也就是自己。如果在Glide.with()时传入的是Fragment类型的参数,则rootRequestManagerFragment指向的是该Fragment所依赖的Activity的SupportRequestManagerFragment。如果Fragment所依赖的SupportRequestManagerFragment存在则直接调用,否则为该Fragment所依赖的Activity创建SupportRequestManagerFragment。
    • rootRequestManagerFragment指向根Activity的SupportRequestManagerFragment。

      在onAttach()方法中,如果rootRequestManagerFragment不是本身,即rootRequestManagerFragment指向根Activity,则将本身保存到childRequestManagerFragments集合中。也就是在这个集合中保存了Activity的所有的子Fragment的SupportRequestManagerFragment。

      当Fragment销毁时,在这个Fragment中的子Fragment会怎么样?当然也是会销毁啊。也就是父Fragment的生命周期的方法被调用时,子Fragment的生命周期的方法也要会被调用。

    • RequestManagerTreeNode接口:这个接口用来保存请求树节点,SupportFragmentRequestManagerTreeNode类继承于这个接口.
    public interface RequestManagerTreeNode {
        /**
         * Returns all descendant {@link RequestManager}s relative to the context of the current {@link RequestManager}.
         */
        Set<RequestManager> getDescendants();
    }
    

      看一下SupportFragmentRequestManagerTreeNode类,这个类只有一个getDescendants()方法,先是利用getDescendantRequestManagerFragments()方法得到一个SupportRequestManagerFragment的集合。
      一个例子,一个Activity有两个Fragment,分别为F1和F2,Activity有一个SRMF(SupportRequestManagerFragment),F1和F2分别有一个SRFM,F1和F2分别又有两个Fragment,分别为F11,F12,F21,F22,这4个Fragment分别拥有SRMF。所以一共有6个SRMF保存在上面所说的rootRequestManagerFragment所指向的集合中。所以当F1生命周期要做出反应时,它的子Fragment分别为F11和F12对应的SRMF也要有相应的反应。但F2的子Fragment的SRMF不做出反应。那怎么得到F1的子Fragment的SRMF,这就是SupportFragmentRequestManagerTreeNode类的作用了。
      接着看。
      在getDescendantRequestManagerFragments()方法中,如果自己不是rootRequestManagerFragment就会在for()循环中遍历返回的rootRequestManagerFragment所指向的集合,这个集合中保存了根Activity的所有的子Fragment的SRMF。接着每遍历一次,就会调用isDescendant()方法进行判断,比如说这个本身的SupportRequestManagerFragment是F1,所有每次都会遍历返回的集合的SPMF是不是F1的子Fragment的SRMF。如果是的话,就将这个SRMF加入集合。
      最后在SupportFragmentRequestManagerTreeNode类getDescendants()方法中得到的都是Fragment的子Fragment的SRMF,最后将子Fragment的SRMF中的RequestManager对象的集合返回。
      所以SupportFragmentRequestManagerTreeNode类getDescendants()方法返回的是Fragment的子Fragment的SRMF的RequestManager对象的集合。

      接着来看RequestManager类

    • RequestManager类实现了LifecycleListener接口。可以启动,停止,管理Glide的Request请求,是实现Glide加载资源的管理类,是Glide生命周期实现的关键类 。

    RequestManager类

    private final Context context;
    private final Lifecycle lifecycle;
    private final RequestManagerTreeNode treeNode;
    private final RequestTracker requestTracker;
    public RequestManager(Context context, Lifecycle lifecycle, RequestManagerTreeNode treeNode) {
            this(context, lifecycle, treeNode, new RequestTracker(), new ConnectivityMonitorFactory());
        }
    
        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;
            ......
            if (Util.isOnBackgroundThread()) {
                new Handler(Looper.getMainLooper()).post(new Runnable() {
                    @Override
                    public void run() {
                        lifecycle.addListener(RequestManager.this);
                    }
                });
            } else {
                lifecycle.addListener(this);
            }
            lifecycle.addListener(connectivityMonitor);
        }
    

      可以看见,在RequestManager的构造器中将RequestManager对象加入到ActivityLifeCycle中去。
      再看看RequestManager类实现的LifeCycleListener接口的方法。

    RequestManager类实现的LifeCycleListener接口的方法(onStop)

    public boolean isPaused() {
            Util.assertMainThread();
            return requestTracker.isPaused();
        }
     public void pauseRequests() {
            Util.assertMainThread();
            requestTracker.pauseRequests();
        }
    @Override
        public void onStop() {
            pauseRequests();
        }
    

      可以看见在这些方法中真正起作用的是RequestTracker。

    • RequestTracker类:所有请求的真正执行者

      来捋一下思路,首先是Glide为了管理生命周期,创建了一个无UI的虚拟的Fragment,在这个Fragment创建的时候就生成了ActivityFragmentLifeCycle生命周期的管理的对象,当Fragment的生命周期变化时就会调用ActivityFragmentLifeCycle的相应的方法。而RequestManager类实现了LifeCycleListener接口,在RequestManager的构造器中会将创建的RequestManager对象加入到
    ActivityFragmentLifeCycle的管理LifeCycleListener接口的集合中去,所以当ActivityFragmentLifeCycle的相应的方法调用时就会调用RequestManager对象的相应方法,而在RequestManager对象的相应方法真正的执行者是RequestTracker

    参考

    Android图片加载框架最全解析(二),从源码的角度理解Glide的执行流程

    相关文章

      网友评论

          本文标题:Glide的with()过程和Glide的生命周期的源码分析

          本文链接:https://www.haomeiwen.com/subject/gytyoftx.html