Glide内存缓存

来源:互联网 发布:陈震媳妇淘宝 编辑:程序博客网 时间:2024/05/17 23:46
Glide缓存分为两个方面内存缓存和磁盘缓存。
主要看一下内存缓存
GenericRequest调用onSizeReady函数,通过Engie.load加载图片.

load先从内存缓存中加载图片,有两个层级,一个是MemoryCache,一个是ActiveResouces。

        EngineResource<?> cached = loadFromCache(key, isMemoryCacheable);        if (cached != null) {            cb.onResourceReady(cached);            if (Log.isLoggable(TAG, Log.VERBOSE)) {                logWithTimeAndKey("Loaded resource from cache", startTime, key);            }            return null;        }        EngineResource<?> active = loadFromActiveResources(key, isMemoryCacheable);        if (active != null) {            cb.onResourceReady(active);            if (Log.isLoggable(TAG, Log.VERBOSE)) {                logWithTimeAndKey("Loaded resource from active resources", startTime, key);            }            return null;        }

内存缓存根据key加载图片。
有两个部分:
1、图片存到内存的;
2、怎样取内存中的图片。


1、 图片存到内存的过程
图片加载完成后才会缓存,首先要看一下加载过程(无缓存、无active )。

        EngineJob engineJob = engineJobFactory.build(key, isMemoryCacheable);        DecodeJob<T, Z, R> decodeJob = new DecodeJob<T, Z, R>(key, width, height, fetcher, loadProvider, transformation,                transcoder, diskCacheProvider, diskCacheStrategy, priority);        EngineRunnable runnable = new EngineRunnable(engineJob, decodeJob, priority);        jobs.put(key, engineJob);        engineJob.addCallback(cb);        engineJob.start(runnable);

这块有几个和加载相关的类:DecodeJob、EngineJob 、EngineRunnable 
DecodeJob:图片原始数据加载、解码
EngineRunnable :一个中间类,DecodeJob和EngineJob的包装 ,调用DecodeJob加载图片数据,数据加载完成通知EngineJob。
EngineJob :处理DecodeJob的加载结果。
 engineJob.start(runnable);提交EngineRunnable 给执行ExecutorService,EngineRunnable的Run方法执行decode():

        private Resource<?> decode() throws Exception {            if (isDecodingFromCache()) {                return decodeFromCache();            } else {                return decodeFromSource();            }        }  
加载图片数据,加载图片数据完成后(EngineRunnable,Run方法)调用:

if (resource == null) {    onLoadFailed(exception);} else {    onLoadComplete(resource);}

只看加载成功,调用onLoadComplete(EngineRunnable中):

    private void onLoadComplete(Resource resource) {        manager.onResourceReady(resource);    }
onLoadComplete调用 manager.onResourceReady(resource);这个manager既是EngineJob
    public EngineRunnable(EngineRunnableManager manager, DecodeJob<?, ?, ?> decodeJob, Priority priority) {        this.manager = manager;        this.decodeJob = decodeJob;        this.stage = Stage.CACHE;        this.priority = priority;    }
class EngineJob implements EngineRunnable.EngineRunnableManager,EngineJob 实现 EngineRunnable.EngineRunnableManager。

EngineJob 在onResourceReady中调用了
    public void onResourceReady(final Resource<?> resource) {        this.resource = resource;        MAIN_THREAD_HANDLER.obtainMessage(MSG_COMPLETE, this).sendToTarget();    }

加载图片数据不在UI线程,所以图片回调到ImageView时得切到UI线程。
MAIN_THREAD_HANDLER初始化(EngineJob ):

private static final Handler MAIN_THREAD_HANDLER = new Handler(Looper.getMainLooper(), new MainThreadCallback());

MAIN_THREAD_HANDLER 发送MSG_COMPLETE告知图片加载完成:
private static class MainThreadCallback implements Handler.Callback {        @Override        public boolean handleMessage(Message message) {            if (MSG_COMPLETE == message.what || MSG_EXCEPTION == message.what) {                EngineJob job = (EngineJob) message.obj;                if (MSG_COMPLETE == message.what) {                    job.handleResultOnMainThread();                } else {                    job.handleExceptionOnMainThread();                }                return true;            }            return false;        }    }

下面是缓存部分
调用job.handleResultOnMainThread()三个主要功能:
a)回调Engine进行ActiveResouce资源缓存
b)回调给ImageView
c)进行MemoryCache

private void handleResultOnMainThread() {        if (isCancelled) {            resource.recycle();            return;        } else if (cbs.isEmpty()) {            throw new IllegalStateException("Received a resource without any callbacks to notify");        }        engineResource = engineResourceFactory.build(resource, isCacheable);        hasResource = true;        engineResource.acquire();        listener.onEngineJobComplete(key, engineResource);        for (ResourceCallback cb : cbs) {            if (!isInIgnoredCallbacks(cb)) {                engineResource.acquire();                cb.onResourceReady(engineResource);            }        }        // Our request is complete, so we can release the resource.        engineResource.release();}
a)回调Engine进行ActiveResouce资源缓存,对应这行代码:listener.onEngineJobComplete(key, engineResource);
listener在Engine构造方法初始化,
 public void onEngineJobComplete(Key key, EngineResource<?> resource) {        Util.assertMainThread();        // A null resource indicates that the load failed, usually due to an exception.        if (resource != null) {            resource.setResourceListener(key, this);            if (resource.isCacheable()) {                activeResources.put(key, new ResourceWeakReference(key, resource, getReferenceQueue()));            }        }        // TODO: should this check that the engine job is still current?        jobs.remove(key);}
b)回调给ImageView,对应 cb.onResourceReady(engineResource);
c)进行Memory缓存,对应engineResource.release();
在a、b时进行active缓存、回调给ImageView时,进行引用计数engineResource.acquire();
在最后对资源进行释放,在引用计数为0时,对资源进行Memory缓存;
void release() {        if (acquired <= 0) {            throw new IllegalStateException("Cannot release a recycled or not yet acquired resource");        }        if (!Looper.getMainLooper().equals(Looper.myLooper())) {            throw new IllegalThreadStateException("Must call release on the main thread");        }        if (--acquired == 0) {            listener.onResourceReleased(key, this);        }}
listener,在onEngineJobComplete中赋值 resource.setResourceListener(key, this)回调到Engine中进行内存缓存。
public void onResourceReleased(Key cacheKey, EngineResource resource) {    Util.assertMainThread();    activeResources.remove(cacheKey);    if (resource.isCacheable()) {        cache.put(cacheKey, resource);    } else {        resourceRecycler.recycle(resource);    }}

2、怎样取内存中的图片
        EngineResource<?> cached = loadFromCache(key, isMemoryCacheable);        if (cached != null) {            cb.onResourceReady(cached);            if (Log.isLoggable(TAG, Log.VERBOSE)) {                logWithTimeAndKey("Loaded resource from cache", startTime, key);            }            return null;        }        EngineResource<?> active = loadFromActiveResources(key, isMemoryCacheable);        if (active != null) {            cb.onResourceReady(active);            if (Log.isLoggable(TAG, Log.VERBOSE)) {                logWithTimeAndKey("Loaded resource from active resources", startTime, key);            }            return null;        }



原创粉丝点击