Glide内存缓存

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



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值