Glide原理

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/YANGDAHUAN/article/details/62225839

Glide是一款十分优秀的图片加载工具,

究其内部机制,发现其优良性能得益于以下几点:

  • 与使用环境生命周期相绑定:RequestManagerFragment & SupportRequestManagerFragment
  • 内存的三级缓存池:LruMemoryResources, ActiveResources, BitmapPool
  • 内存复用机制:BitmapPool

 

Glide中一个重要特性是Request可以随Activity或Fragment的onStart而resume,onStop而pause,onDestroy而clear,从而节约流量和内存,并且防止内存泄露,这一切都由Glide在内部实现了,前提是Glide.with()方法中尽量传入Activity或Fragment,而不是Application,不然没办法进行生命周期管理

 

而现在,我自己就有这种需求,所以我需要去看一下Glide是如何实现这一功能的

 

首先是Glide.with()方法

 

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

 

 

 

这里的RequestManagerRetriever.get()方法是获取了RequestManagerRetriever的对象,而这个类的对象的作用

 

/**
 * A collection of static methods for creating new {@link com.bumptech.glide.RequestManager}s or retrieving existing
 * ones from activities and fragment.
 */
public class RequestManagerRetriever implements Handler.Callback

如备注所说,是用于创建一个新的RequestManager或者从Activity或Fragment获取一个已经存在的RequestManager对象

 

 

而到了retriver.get(activity)进去看一下

 

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public RequestManager get(Activity activity) {
	//这里首先判断是否在主线程,以及当前的版本是否小于HONEYCOMB(11---> 3.0.x)
        if (Util.isOnBackgroundThread() || Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
            return get(activity.getApplicationContext());
        } else {//发现是主线程并且当前版本大于等于11(Android 3.0.x)时
            assertNotDestroyed(activity);//如果当前版本大于等于17(4.2)并且activity已经destroy,就会抛出错误
            android.app.FragmentManager fm = activity.getFragmentManager();
            return fragmentGet(activity, fm);
        }
    }

在第一个判断中,满足条件的话,即在子现成,或者版本小于11时,会直接走

getApplicationManager(context)

 

这一条路线就跟监听Activity生命周期无关了,所以不看

 

而另一条路线我们继续

 

 

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    RequestManager fragmentGet(Context context, android.app.FragmentManager fm) {
	//
        RequestManagerFragment current = getRequestManagerFragment(fm);//获取空白的Fragment
        RequestManager requestManager = current.getRequestManager();//获取空白Fragment中的RequestManager
        if (requestManager == null) {
		//发现没有RequestManager则立刻新建一个,新建时,将自己的Lifecycler传入
            requestManager = new RequestManager(context, current.getLifecycle(), current.getRequestManagerTreeNode());
            current.setRequestManager(requestManager);
        }
        return requestManager;
    }


    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
    RequestManagerFragment getRequestManagerFragment(final android.app.FragmentManager fm) {
	//根据tag找到已经添加的Fragment
        RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
        if (current == null) {
		//根据FragmentManager对象去本地管理的缓存中寻找Fragment
            current = pendingRequestManagerFragments.get(fm);
            if (current == null) {//还是没有找到,则新建
                current = new RequestManagerFragment();
                pendingRequestManagerFragments.put(fm, current);
                fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();//添加Fragment
                handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();//进入队列去删除FragmentManager
            }
        }
        return current;
    }

   @Override
    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;
		// fragment创建好后,将之前的FragmentManager删除掉,因为已经用不上它了,同一个Activity或父Fragment中只会创建一个SupportRequestManagerFragment
                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;
    }


可以看到,这边就是一个新建空白Fragment并将空白Fragment与RequestManager绑定的过程

 

 

 

 

 

到了这里,基本原理已经清楚了,因为到了这里已经给Activity添加了一个Fragment,已经可以从自定义的Fragment中获取各个生命周期了,那么哪些生命周期比较准确呢?我们需要一个Fragment与Activity的生命周期的关系图:


有了这个生命周期的对照,有了之前到绑定的逻辑,其实已经可以自己写出来了,神奇的监听生命周期的核心就在于添加一个

Fragment,之后的就是在Fragment的各个生命周期进行通知回调即可,至于其他的细节处理,就不是那么重要了

 

那么,接下来我就自己写一个监听试试看

 

 

首先是框架方面我需要哪几个类

SupportActLifeListenerFragment 空白的Fragment,用于获取Activity的生命周期
ActLifeListenerManager 用于管理ActListener以及生命周期的回调执行
ActListener 用于给外部传入的回调接口的母类
ActLifeListener extends ActListener 用于监听Activity或Fragment的生命周期的接口
LifeAttchManager 用于给指定的Activity添加生命周期的监听的开放调用类

 

然后大概是什么个流程

 

流程相当简单,只是因为关系到Activity,所以需要注意不要持有Activity导致无法回收等问题

 

代码我就不直接贴了,可以去我的github项目上去看,运行的demo为:demoactivitylifelistener

项目地址https://github.com/yangdeyouxi/DevelopTools/

 

 

 

 

 

 

展开阅读全文

没有更多推荐了,返回首页