资讯专栏INFORMATION COLUMN

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

Kosmos / 1677人阅读

摘要:从这段代码入手分析分析从这段代码可以看出无论传入的是还是或者干脆传入或都会调用这个方法而这个方法生成两个对象对象,并把它加到上对象这两个对象拥有共同的对象对象,当系统调用的生命周期,的生命周期随之被调用来处理列表,将的生命周期与的生命周期联

从这段代码入手分析Glide

    Glide.with(context)
       .load(url)
       .placeholder(R.drawable.loading)
       .error(R.drawable.avatar)
       .listener(new RequestListener() {
            @Override
            public boolean onException(Exception e, String model, Target target, boolean isFirstResource) {
                return false;
            }

            @Override
            public boolean onResourceReady(GlideDrawable resource, String model, Target target, boolean  
                 isFromMemoryCache, boolean isFirstResource) {
                 LogUtil.logV("loadPhotoDebug", "loadAvatar onResourceReady url = " + url);
                 if (isSimpleImage(tagView.getTag(), url)) {
                     return false;
                 }
                 mImageView.setImageResource(R.drawable.loading);
                 return true;
           }
       })
      .bitmapTransform(new CropCircleTransformation(context))
      .into(mImageView);
1.Glide.with(context)分析

Glide.java:

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

RequestManagerRetriever.java:

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

从这段代码可以看出无论Glide.with传入的Context是Fragment还是Activity或者干脆传入Framgent或FragemtnActivity,都会调用supportFragmentGet这个方法

RequestManagerRetriever.java:

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

而supportFragmentGet这个方法生成两个对象:
1.SupportRequestManagerFragment对象, 并把它加到FragmentManager上;
2.RequestManager对象
这两个对象拥有共同的对象LifeStyle对象,当Android系统调用SupportRequestManagerFragment的生命周期,RequestManger的生命周期随之被调用来处理Request列表,
将Fragment的生命周期与RequestManger的生命周期联系起来:

SupportRequestManagerFragment.java:

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

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

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

RequestManager.java

public class RequestManager implements LifecycleListener {
    RequestManager(Context context, final Lifecycle lifecycle, RequestManagerTreeNode treeNode,
            RequestTracker requestTracker, ConnectivityMonitorFactory factory) {
        ... ...
        this.lifecycle = lifecycle;
        ConnectivityMonitor connectivityMonitor = factory.build(context,
                new RequestManagerConnectivityListener(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);
    }
    
    
    @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();
    }

如果传入的是Applicaton Context,

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

会得到一个单例的RequestManager对象,RequestManager绑定的生命周期并不会调用onStop,onDestroy,

ApplicationLifecycle.java:

    class ApplicationLifecycle implements Lifecycle {
    @Override
    public void addListener(LifecycleListener listener) {
        listener.onStart();
    }
}

总结:Glide.with(Context)将Activity的生命周期与RequestManager针对的request的处理联系起来,

 传入ApplicationContext,会得到一个单例的RequestManager对象;
 传入Activity Context,会得到一个属于一个Activity的RequestManager对象;

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/70708.html

相关文章

  • Glide源码分析

    摘要:版本问题如何实现与生命周期的绑定如何实现缓存如何实现图片压缩如何实现与生命周期的绑定创建将其与传入的生命周期绑定这样做的好处是当时,也会做相应操作,如停掉图片加载绑定首先无论传入的是什么,只要是在子线程中调用创建的与绑定,这样创建的的生命周 版本4.9.0 问题 Glide如何实现与生命周期的绑定? Glide如何实现缓存? Glide如何实现图片压缩? Glide如何实现与生命周...

    youkede 评论0 收藏0
  • 金三银四,2019大厂Android高级工程师面试题整理

    摘要:原文地址游客前言金三银四,很多同学心里大概都准备着年后找工作或者跳槽。最近有很多同学都在交流群里求大厂面试题。 最近整理了一波面试题,包括安卓JAVA方面的,目前大厂还是以安卓源码,算法,以及数据结构为主,有一些中小型公司也会问到混合开发的知识,至于我为什么倾向于混合开发,我的一句话就是走上编程之路,将来你要学不仅仅是这些,丰富自己方能与世接轨,做好全栈的装备。 原文地址:游客kutd...

    tracymac7 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<