// 1.内存缓存中是否存在,默认为LruMemoryCache
 Bitmap bmp = configuration.memoryCache.get(memoryCacheKey);
 if (bmp != null && !bmp.isRecycled()) {
 // …省略部分代码
 listener.onLoadingComplete(uri, imageAware.getWrappedView(), bmp);
 } else {
 ImageLoadingInfo imageLoadingInfo = new ImageLoadingInfo(uri, imageAware, targetSize, memoryCacheKey,
 options, listener, progressListener, engine.getLockForUri(uri));
 // 封装成LoadAndDisplayImageTask从本地缓存查找/发送网络请求
 LoadAndDisplayImageTask displayTask = new LoadAndDisplayImageTask(engine, imageLoadingInfo,
 defineHandler(options));
 if (options.isSyncLoading()) {
 displayTask.run();
 } else {
 engine.submit(displayTask);
 }
 }
 }
 }
四、内存缓存
内存缓存LruMemoryCache是通过LinkedHashMap实现了最近最少使用算法。
public class LruMemoryCache implements MemoryCache {
private final LinkedHashMap<String, Bitmap> map;
public LruMemoryCache(int maxSize) {
 if (maxSize <= 0) {
 throw new IllegalArgumentException(“maxSize <= 0”);
 }
 this.maxSize = maxSize;
 this.map = new LinkedHashMap<String, Bitmap>(0, 0.75f, true);
 }
 @Override
 public final Bitmap get(String key) {
 if (key == null) {
 throw new NullPointerException(“key == null”);
 }
synchronized(this) {
 return map.get(key);
 }
 }
/**
- Caches {@code Bitmap} for {@code key}. The Bitmap is moved to the head of the queue.
 */
 @Override
 public final boolean put(String key, Bitmap value) {
 if (key == null || value == null) {
 throw new NullPointerException(“key == null || value == null”);
 }
synchronized(this) {
 size += sizeOf(key, value);
 Bitmap previous = map.put(key, value);
 if (previous != null) {
 size -= sizeOf(key, previous);
 }
 }
trimToSize(maxSize);
 return true;
 }
 @Override
 public final Bitmap remove(String key) {
 if (key == null) {
 throw new NullPointerException(“key == null”);
 }
synchronized(this) {
 Bitmap previous = map.remove(key);
 if (previous != null) {
 size -= sizeOf(key, previous);
 }
 return previous;
 }
 }
 }
五、LinkedHashMap实现LRU
LRU是最近最少使用算法,实现的算法有多种,比如对每个数据都新增一个时间戳字段等;考虑到算法执行效率,一般采用链表+HashMap的实现方式。
 LinkedHashMap内部实现LRU是通过HashMap+双链表方式实现的,当需要插入新的数据项的时候,如果新数据项在链表中存在(一般称为命中),则把该节点移到链表头部,如果不存在,则新建一个节点,放到链表头部。在访问数据的时候,如果数据项在链表中存在,则把该节点移到链表头部,否则返回-1。这样,头节点存放最近被访问的数据项,尾节点存放最久未访问的数据项,若缓存满了,则删除尾节点即可。
public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V> {
 // 头节点,最近被访问的数据
 transient LinkedHashMapEntry<K,V> head;
 // 尾节点,最久未访问的数据
 transient LinkedHashMapEntry<K,V> tail;
最后我还整理了很多Android中高级的PDF技术文档。以及一些大厂面试真题解析文档。需要的朋友都可以点击GitHub直接获取方式

Android高级架构师之路很漫长,一起共勉吧!
%E8%96%AA%EF%BC%81.md)直接获取方式**
[外链图片转存中…(img-qvDt4jOp-1643793631779)]
Android高级架构师之路很漫长,一起共勉吧!










