Glide图片加载框架设计

Glide 资源封装

    key       --对value的唯一性进行描述 

    value   --对bitmap的封装(+1 -1 释放)

public class Glide {

    RequestManagerRetriverretriver;

    public Glide(RequestManagerRetriver retriver) {

        this.retriver = retriver;

    }

public static RequestManagerwith(FragmentActivity fragmentActivity) {

return getRetriever(fragmentActivity).get(fragmentActivity);

    }

public static RequestManagerwith(Activity activity) {

return getRetriever(activity).get(activity);

    }

private static RequestManagerwith(Context context) {

return getRetriever(context).get(context);

    }

/**

* RequestManager有我们的RequestManagerRetriver去创建的

    * @return

    */

    public static RequestManagerRetrivergetRetriever(Context context){

return Glide.get(context).getRetriver();

    }

// Glide 是 new出来的 -- 转变

    public static Glideget(Context context) {

return new GlideBuilder().build();

    }

/**

* RequestManagerRetriver

    * @return

    */

    public RequestManagerRetrivergetRetriver() {

return retriver;

    }

public class RequestManagerRetriver {

public RequestManagerget(FragmentActivity fragmentActivity){

return new RequestManager(fragmentActivity);

    }

public RequestManagerget(Activity activity){

return new RequestManager(activity);

    }

public RequestManagerget(Context context){

return new RequestManager(context);

    }

}

/**

* 创建Glide

    * @return

    */

    public Glidebuild() {

RequestManagerRetriver requestManagerRetriver =new RequestManagerRetriver();

        Glide glide =new Glide(requestManagerRetriver);

        return glide;

    }

}

/**

* 唯一的描述

*/

public class Key {

private Stringkey; // 例如:ac037ea49e34257dc5577d1796bb137dbaddc0e42a9dff051beee8ea457a4668

    public StringgetKey() {

return key;

    }

public void setKey(String key) {

this.key = key;

    }

/**

* sha256(https://cn.bing.com/sa/simg/hpb/LaDigue_EN-CA1115245085_1920x1080.jpg)之前

* ac037ea49e34257dc5577d1796bb137dbaddc0e42a9dff051beee8ea457a4668 处理后

    * @param key

    */

    public Key(String key) {

//this.key = key;

      this.key = Tool.getSHA256StrJava(key);

    }

}


/**

* 对Bitmap的封装

*/

public class Value {

private final StringTAG = Value.class.getSimpleName();

    // 单利模式

    private static Valuevalue;

    public static ValuegetInstance() {

if (null ==value) {

synchronized (Value.class) {

if (null ==value) {

value =new Value();

                }

}

}

return value;

    }

private BitmapmBitmap;

    // 使用计数

    private int count;

    // 监听

    private ValueCallbackcallback;

    // 定义key

    private Stringkey;

    public BitmapgetmBitmap() {

return mBitmap;

    }

public void setmBitmap(Bitmap mBitmap) {

this.mBitmap = mBitmap;

    }

public int getCount() {

return count;

    }

public void setCount(int count) {

this.count = count;

    }

public ValueCallbackgetCallback() {

return callback;

    }

public void setCallback(ValueCallback callback) {

this.callback = callback;

    }

public StringgetKey() {

return key;

    }

public void setKey(String key) {

this.key = key;

    }

/**

    * TODO 使用一次 就 加一

    */

    public void useAction() {

Tool.checkNotEmpty(mBitmap);

        if (mBitmap.isRecycled()) {// 已经被回收了

            Log.d(TAG, "useAction: 已经被回收了");

return;

        }

Log.d(TAG, "useAction: 加一 count:" +count);

        count ++;

    }

/**

    * TODO 使用完成(不使用) 就 减一

    * count -- <= 0  不再使用了

*/

    public void nonUseAction() {

if (count -- <=0 &&callback !=null) {

// 回调告诉外界,不再使用了

            callback.valueNonUseListener(key, this);

        }

Log.d(TAG, "useAction: 减一 count:" +count);

    }

/**

    * TODO 释放

    */

    public void recycleBitmap() {

if (count >0) {

Log.d(TAG, "recycleBitmap: 引用计数大于0,证明还在使用中,不能去释放...");

return;

        }

if (mBitmap.isRecycled()) {// 被回收了

            Log.d(TAG, "recycleBitmap: mBitmap.isRecycled() 已经被释放了...");

return;

        }

mBitmap.recycle();

        value =null;

        System.gc();

    }

}

public interface ValueCallback {

/**

* 监听的方法(Value不再使用了)

    * @param key

    * @param value

    */

    public void valueNonUseListener(String key, Value value);

}

Glide 活动缓存      

回收机制:GC扫描的时候回收,移除容器(GC被动移除)弱引用

容器管理方式:资源的封装key,(弱引用

手动移除的区分(手动移除map还是GC移除)

关闭线程

value监听加入

/**

* 活动缓存 -- 真正被使用的资源

*/

public class ActiveCache {

// 容器

    private MapmapList=new HashMap<>();

    private MapmapValueList=new HashMap<>();

    private ReferenceQueuequeue;//目的:为了监听这个弱引用是否被回收了

    private boolean isClosedThread;

    private Threadthread;

    private boolean isShoudongRemove;

    private ValueCallbackvalueCallback;

    public ActiveCache(ValueCallback valueCallback){

this.valueCallback=valueCallback;

    }

/**

* TODO 添加 活动缓存

    * @param key

    * @param value

    */

    public void put(String key,Value value){

Tool.checkNotEmpty(key);

        // 绑定Value的监听 --> Value发起来的(Value没有被使用了,就会发起这个监听,给外界业务需要来使用)

        value.setCallback(valueCallback);

        //存储

        mapList.put(key,new CustomoWeakReference(value,getQueue(),key));

        mapValueList.put(key,value.getmBitmap());

    }

/**

* TODO 给外界获取Value

    * @param key

    * @return

    */

    public Valueget(String key){

CustomoWeakReference valueWeakReference=mapList.get(key);

        if(null!=valueWeakReference){

Value value=valueWeakReference.getValue();

            value.setmBitmap(mapValueList.get(key));

            value.setKey(key);

            // bug每次 value信息一致

            Log.d("activeCache", "get: Inputkey:" + key +" --- value:" + value.getmBitmap() +"对应 key:" + value.getKey());

            return value;

        }

return null;

    }

/**

* TODO 手动移除

    * @param key

    * @return

    */

    public Valueremove(String key){

isShoudongRemove=true;

        WeakReference valueWeakReference=mapList.remove(key);

        isShoudongRemove=false;

        if(null!=valueWeakReference){

return valueWeakReference.get();

        }

return null;

    }

/**

* TODO 释放 关闭线程

*/

    public void closeThread(){

isClosedThread=true;

        mapValueList.clear();

        System.gc();

    }

/**

* 监听弱引用 成为弱引用的子类  为什么要成为弱引用的子类(目的:为了监听这个弱引用 是否被回收了)

*/

    class  CustomoWeakReferenceextends WeakReference{

private Stringkey;

        private Valuevalue;

        public CustomoWeakReference(Value value, ReferenceQueue queue,String key) {

super(value, queue);

            this.key=key;

            this.value=value;

        }

public ValuegetValue(){

return this.value;

        }

/**

* 为了监听 弱引用被回收,被动移除的

        * @return

        */

    }

public ReferenceQueuegetQueue(){

if(queue==null){

queue=new ReferenceQueue<>();

            // 监听这个弱引用 是否被回收了

            thread=new Thread(){

@Override

                public void run() {

super.run();

                    while (!isClosedThread) {

if(!isShoudongRemove){

// queue.remove(); 阻塞式的方法

                            try {

Reference remove=queue.remove();// 如果已经被回收了,就会执行到这个方法

                                CustomoWeakReference weakReference=(CustomoWeakReference) remove;

                                // 移除容器    !isShoudonRemove:为了区分手动移除 和 被动移除

                                if(mapList!=null&&!mapList.isEmpty()&&!mapValueList.isEmpty()){

mapList.remove(weakReference.key);

                                    mapValueList.remove(weakReference.key);

                                }

}catch (Exception e) {

e.printStackTrace();

                            }

}

}

}

};

            thread.start();

        }

return queue;

    }

}

Glide 内存缓存

LRU算法:最近没有使用的元素,会自动被移除掉

职责:

活动缓存:给正在使用的资源存储的,弱引用

内存缓存:为第二次缓存服务,LRU算法

LRU算法: ---> 最近没有使用的元素,会自动被移除掉

把最近没有使用到的元素给移除

LruCache v4:

利用LinkedHashMap

LinkedHashMap: true==拥有访问排序的功能 (最少使用元素算法-LRU算法)

put:

    1.如果是重复的key,会被移除掉一个

    key=15151511551

    previous = key=15151511551

    entryRemoved

    2.trimToSize 移除哪些最近没有使用的元素 ---》 entryRemoved


public class MemoryCacheextends LruCache {

private boolean shouDonRemove;

    //TODO 手动移除

    public ValueshouDonRemove(String key){

shouDonRemove=true;

        Value value=remove(key);

        shouDonRemove=false; // !shoudonRemove == 被动的

        return value;

    }

private MemoryCacheCallbackmemoryCacheCallback;

    public void setMemoryCacheCallback(MemoryCacheCallback memoryCacheCallback){

this.memoryCacheCallback=memoryCacheCallback;

    }

/**

* 传入元素最大值,给LruCache

    * @param maxSize

    */

/**

    * @param maxSize for caches that do not override {@link #sizeOf}, this is

*                the maximum number of entries in the cache. For all other caches,

*                this is the maximum sum of the sizes of the entries in this cache.

*/

    public MemoryCache(int maxSize) {

super(maxSize);

    }

@Override

    protected int sizeOf(@NonNull String key, @NonNull Value value) {

Bitmap bitmap=value.getmBitmap();

        int sdkInt= Build.VERSION.SDK_INT;

        if(sdkInt>=Build.VERSION_CODES.KITKAT){

return bitmap.getAllocationByteCount();

        }

return bitmap.getByteCount();

    }

/**

* 1.重复的key

* 2.最少使用的元素会被移除

    * @param evicted

    * @param key

    * @param oldValue

    * @param newValue

    */

    @Override

    protected void entryRemoved(boolean evicted, @NonNull String key, @NonNull Value oldValue, @Nullable Value newValue) {

super.entryRemoved(evicted, key, oldValue, newValue);

        if(memoryCacheCallback!=null&&!shouDonRemove){

memoryCacheCallback.entryRemovedMemoryCache(key,oldValue);

        }

}

}


/**

* 内存缓存中,元素被移除的接口回调

*/

    

/**

* 内存缓存中移除的 key--value

    * @param key

    * @param oldValue

    */

    public void entryRemovedMemoryCache(String key, Value oldValue);

}

Glide 磁盘缓存

保存时间比较长,保存在本地磁盘,文件的形式存储,(不再是保存在内存中,而是磁盘中)

Lru算法:最近没有使用的会被优先自动移除掉

LruCache :  Android中的v4;

LruCache :访问排序。底层利用lickedMap集合实现

引用JakeWharton大神的DiskLruCache

/**

* 磁盘缓存的封装

*/

public class DiskLruCacheImpl {

private final StringTAG = DiskLruCacheImpl.class.getSimpleName();

    // SD/disk_lru_cache_dir/ac037ea49e34257dc5577d1796bb137dbaddc0e42a9dff051beee8ea457a4668

    private final StringDISKLRU_CACHE_DIR ="disk_lru_cache_dir"; // 磁盘缓存的的目录

    private final int APP_VERSION =1; // 我们的版本号,一旦修改这个版本号,之前的缓存失效

    private final int VALUE_COUNT =1; // 通常情况下都是1

    private final long MAX_SIZE =1024 *1024 *100; // 以后修改成 使用者可以设置的  注意:可以自己去自动配置

    private DiskLruCachediskLruCache;

    public DiskLruCacheImpl() {

File file =new File(Environment.getExternalStorageDirectory() + File.separator +DISKLRU_CACHE_DIR);

        try {

diskLruCache = DiskLruCache.open(file, APP_VERSION, VALUE_COUNT, MAX_SIZE);

        }catch (IOException e) {

e.printStackTrace();

        }

}

// TODO put

    public void put(String key, Value value) {

Tool.checkNotEmpty(key);

        DiskLruCache.Editor editor =null;

        OutputStream outputStream =null;

        try {

editor =diskLruCache.edit(key);

            outputStream = editor.newOutputStream(0);// index 不能大于 VALUE_COUNT

            Bitmap bitmap = value.getmBitmap();

            bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream); // 把bitmap写入到outputStream

            outputStream.flush();

        }catch (IOException e) {

e.printStackTrace();

            // 失败

            try {

editor.abort();

            }catch (IOException e1) {

e1.printStackTrace();

                Log.e(TAG, "put: editor.abort() e:" + e.getMessage());

            }

}finally {

try {

editor.commit(); // sp 记得一定要提交

                diskLruCache.flush();

            }catch (IOException e) {

e.printStackTrace();

                Log.e(TAG, "put: editor.commit(); e:" + e.getMessage());

            }

if (outputStream !=null) {

try {

outputStream.close();

                }catch (IOException e) {

e.printStackTrace();

                    Log.e(TAG, "put: outputStream.close(); e:" + e.getMessage());

                }

}

}

}

// TODO get

    public Valueget(String key) {

Tool.checkNotEmpty(key);

        InputStream inputStream =null;

        try {

DiskLruCache.Snapshot snapshot =diskLruCache.get(key);

            // 判断快照不为null的情况下,在去读取操作

            if (null != snapshot) {

Value value = Value.getInstance();

                inputStream = snapshot.getInputStream(0);// index 不能大于 VALUE_COUNT

                Bitmap bitmap = BitmapFactory.decodeStream(inputStream);

                value.setmBitmap(bitmap);

                // 保存key 唯一标识

                value.setKey(key);

                return value;

            }

}catch (IOException e) {

e.printStackTrace();

        }finally {

if (null != inputStream) {

try {

inputStream.close();

                }catch (IOException e) {

e.printStackTrace();

                    Log.e(TAG, "get: inputStream.close(); e:" + e.getMessage());

                }

}

}

return null; // 为了后续好判断

    }

}

Glide 生命周期

组拼之前的所有所有内容---glide

生命周期的管理:application不能去管理,FragmentActivity和Activity可以去管理

管理的方式:在Activity的组件上,附件fragment,通过fragment的监听组件的生命周期

Activity---app fragment

AppCompatActivity---androidx包fragment

为什么发送一次handler?

我们的Android基于handler消息的,LAUNCH_ACTIVITY,为了让我们的fragment,不要在排队中,为了下次可以取出来移除Handler

public class ActivityFragmentManagerextends Fragment {

public ActivityFragmentManager(){}

private LifecycleCallbacklifecycleCallback;

    @SuppressLint("ValidFragment")

public ActivityFragmentManager(LifecycleCallback lifecycleCallback) {

this.lifecycleCallback = lifecycleCallback;

    }

@Override

    public void onStart() {

super.onStart();

        if(lifecycleCallback!=null){

lifecycleCallback.glideInitAction();

        }

}

@Override

    public void onStop() {

super.onStop();

        if (lifecycleCallback !=null) {

lifecycleCallback.glideStopAction();

        }

}

@Override

    public void onDestroy() {

super.onDestroy();

        if (lifecycleCallback !=null) {

lifecycleCallback.glideRecycleAction();

        }

}

}

public class FragmentActivityFragmentManagerextends Fragment {

public FragmentActivityFragmentManager(){}

private LifecycleCallbacklifecycleCallback;

    public FragmentActivityFragmentManager(LifecycleCallback lifecycleCallback) {

this.lifecycleCallback = lifecycleCallback;

    }

@Override

    public void onStart() {

super.onStart();

        if (lifecycleCallback !=null) {

lifecycleCallback.glideInitAction();

        }

}

@Override

    public void onStop() {

super.onStop();

        if (lifecycleCallback !=null) {

lifecycleCallback.glideStopAction();

        }

}

@Override

    public void onDestroy() {

super.onDestroy();

        if (lifecycleCallback !=null) {

lifecycleCallback.glideRecycleAction();

        }

}

}

public interface LifecycleCallback {

// 生命周期初始化了

    public void glideInitAction();

    // 生命周期 停止了

    public void glideStopAction();

    // 生命周期 释放 操作了

    public void glideRecycleAction();

}

Glide 加载图片

组拼接之前的所有内容(缓存) --> Glide

加载资源 --》 缓存 ---》网络/SD/ 加载资源 成功后 --》资源 保存到缓存中

/**

* 加载外部资源 成功与失败的 回调

*/

public interface ResponseListener {

public void responseSuccess(Value value);

    public void responseException(Exception e);

}

/**

* 加载外部资源 标准

*/

public interface ILoadData {

// 加载外部资源的行为

    public ValueloadResource(String path, ResponseListener responseListener, Context context);

}

/**

* 加载图片资源

*/

public class RequestTargetEngineimplements LifecycleCallback, ValueCallback, MemoryCacheCallback, ResponseListener {

private final StringTAG = RequestTargetEngine.class.getSimpleName();

    /**

* 内存缓存发出的

* LRU最少使用的元素会被移除

    * @param key

    * @param oldValue

    */

    @Override

    public void entryRemovedMemoryCache(String key, Value oldValue) {

// 添加到复用池 ...... ,空留的功能点

    }

@Override

    public void glideInitAction() {

Log.d(TAG, "glideInitAction: Glide生命周期之 已经开启了 初始化了....");

    }

@Override

    public void glideStopAction() {

Log.d(TAG, "glideInitAction: Glide生命周期之 已经停止中 ....");

    }

@Override

    public void glideRecycleAction() {

Log.d(TAG, "glideInitAction: Glide生命周期之 进行释放操作 缓存策略释放操作等 >>>>>> ....");

        if (activeCache !=null) {

activeCache.closeThread(); // 把活动缓存给释放掉

        }

}

private ActiveCacheactiveCache;// 活动缓存

    private MemoryCachememoryCache;// 内存缓存

    private DiskLruCacheImpldiskLruCache;// 磁盘缓存

    private final int MEMORY_MAX_SIZE =1024 *1024 *60;

    public RequestTargetEngine() {

if (activeCache ==null) {

activeCache =new ActiveCache(this);

        }

if (memoryCache ==null) {

memoryCache =new MemoryCache(MEMORY_MAX_SIZE);

            memoryCache.setMemoryCacheCallback(this);

        }

diskLruCache =new DiskLruCacheImpl();

        Log.e("DissswkLruCach","RequestTargetEngine");

    }

private Stringpath;

    private ContextglideContext;

    private Stringkey; // ac037ea49e34257dc5577d1796bb137dbaddc0e42a9dff051beee8ea457a4668

    private ImageViewimageView; // 显示的目标

    /**

* RequestManager传递的值

*/

    public void loadValueInitAction(String path, Context glideContext) {

this.path = path;

        this.glideContext = glideContext;

        key =new Key(path).getKey();

    }

public void into(ImageView imageView) {

this.imageView = imageView;

        Tool.checkNotEmpty(imageView);

        Tool.assertMainThread();

        // TODO 加载资源 --》 缓存 ---》网络/SD/ 加载资源 成功后 --》资源 保存到缓存中 >>>

        Value value = cacheAction();

        if (value !=null) {

// 使用完成了 减一

            value.nonUseAction();

            imageView.setImageBitmap(value.getmBitmap());

        }

}

// TODO 加载资源 --》 缓存 ---》网络/SD/ 加载资源 成功后 --》资源 保存到缓存中 >>>

    private ValuecacheAction() {

// TODO 第一步,判断活动缓存是否有资源,如果有资源 就返回, 否则就继续往下找

        Value value =activeCache.get(key);

        if (null != value) {

Log.d(TAG, "cacheAction: 本次加载是在(活动缓存)中获取的资源>>>");

            // 返回 代表 使用了一次 Value

            value.useAction();

            return value;

        }

// TODO 第二步,从内存缓存中去找,如果找到了,内存缓存中的元素 “移动” 到 活动缓存, 然后再返回

        value =memoryCache.get(key);

        if (null != value) {

// 移动操作

            memoryCache.shouDonRemove(key); // 移除内存缓存

            activeCache.put(key, value); // 把内存缓存中的元素 加入到活动缓存中

            Log.d(TAG, "cacheAction: 本次加载是在(内存缓存)中获取的资源>>>");

            // 返回 代表 使用了一次 Value

            value.useAction(); // 使用了一次 加一

            return value;

        }

// TODO 第三步,从磁盘缓存中去找,如果找到了,把磁盘缓存中的元素 加入到 活动缓存中

        value =diskLruCache.get(key);

        if (null != value) {

// 把磁盘缓存中的元素 --> 加入到活动缓存中

            activeCache.put(key, value);

            // 把磁盘缓存中的元素 --> 加入到内存缓存中

// memoryCache.put(key, value);

            Log.d(TAG, "cacheAction: 本次加载是在(磁盘缓存)中获取的资源>>>");

            // 返回 代表 使用了一次 Value

            value.useAction(); // 使用了一次 加一

            return value;

        }

// TODO 第四步,真正的去加载外部资源了, 去网络上加载/去SD本地上加载

        value =new LoadDataManager().loadResource(path, this, glideContext);

        if (value !=null)

return value;

return null;

    }

// 加载外部资源成功

    @Override

    public void responseSuccess(Value value) {

if (null != value) {

saveCahce(key, value);

            imageView.setImageBitmap(value.getmBitmap());

        }

}

/**

* 保存到缓存中

    * @param key

    * @param value

    */

    private void saveCahce(String key, Value value) {

Log.d(TAG, "saveCahce: >>>>>>>>>>>>>>>>>>>>>> 加载外部资源成功后,保存到缓存中 key:" + key +" value:" + value);

        value.setKey(key);

        if (diskLruCache !=null) {

diskLruCache.put(key, value); // 保存到磁盘缓存中

        }

}

// 加载外部资源失败

    @Override

    public void responseException(Exception e) {

Log.d(TAG, "responseException: 加载外部资源失败 e:" + e.getMessage());

    }

/**

* 活动缓存间接的调用Value所发出的

* 回调告诉外界,Value资源不再使用了

* 监听的方法(Value不再使用了)

    * @param key

    * @param value

    */

    @Override

    public void valueNonUseListener(String key, Value value) {

// 把活动缓存操作的Value资源 加入到 内存缓存

        if (key !=null && value !=null) {

memoryCache.put(key, value);

        }

}

}

public class LoadDataManagerimplements ILoadData, Runnable {

private final StringTAG = LoadDataManager.class.getSimpleName();

    private Stringpath;

    private ResponseListenerresponseListener;

    private Contextcontext;

    @Override

    public ValueloadResource(String path, ResponseListener responseListener, Context context) {

this.path = path;

        this.responseListener = responseListener;

        this.context = context;

        // 加载 网络图片/SD本地图片/..

        Uri uri = Uri.parse(path);

        // 网络图片

        if ("HTTP".equalsIgnoreCase(uri.getScheme()) ||"HTTPS".equalsIgnoreCase(uri.getScheme())) {

new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS, new SynchronousQueue()).execute(this);

        }

return null;

    }

@Override

    public void run() {

InputStream inputStream =null;

        HttpURLConnection httpURLConnection =null;

        try {

URL url =new URL(path);

            URLConnection urlConnection = url.openConnection();

            httpURLConnection = (HttpURLConnection) urlConnection;

            httpURLConnection.setConnectTimeout(5000);

            final int responseCode = httpURLConnection.getResponseCode();

            if(HttpURLConnection.HTTP_OK==responseCode){

inputStream=httpURLConnection.getInputStream();

                final Bitmap bitmap= BitmapFactory.decodeStream(inputStream);

                //成功  切换主线程

                new Handler(Looper.getMainLooper()).post(new Runnable() {

@Override

                    public void run() {

Value value=Value.getInstance();

                        value.setmBitmap(bitmap);

                        // 回调成功

                        responseListener.responseSuccess(value);

                    }

});

            }else {

//失败 切换主线程

                new Handler(Looper.getMainLooper()).post(new Runnable() {

@Override

                    public void run() {

responseListener.responseException(new IllegalStateException("请求失败 请求码:" +responseCode));

                    }

});

            }

}catch (Exception e) {

e.printStackTrace();

        }finally {

if(inputStream!=null){

try {

inputStream.close();

                }catch (IOException e) {

e.printStackTrace();

                    Log.d(TAG, "run: 关闭 inputStream.close(); e:" + e.getMessage());

                }

}

if(httpURLConnection!=null){

httpURLConnection.disconnect();

            }

}

}

}

总结:

第一次的时候,去网络下载图片,保存到磁盘缓存中(/sd/disk_lru_cache_dir/key)

第二次的时候,直接再活动缓存中,找到了资源

第三次的时候,直接再活动缓存中,找到了资源

第N次的时候,直接再活动缓存中,找到了资源

把Activity给返回回去的时候,进行释放,活动缓存的释放

又一次加载的时候,从内存缓存中获取了

下一次加载的时候,就是从活动缓存获取了


把App给杀掉

整个活动缓存,整个内存缓存,都没有了

所以从磁盘缓存中获取

---

LRU:LRU小知识点

---

1.活动缓存,HashMap管理的,用到了弱引用去回收移除 ----> 活动缓存(Value没有被使用了)移除后 交给 内存缓存

2.内存缓存,内存缓存作为第二道防线,LRU算法的

3.磁盘缓存,缓存中最后一道防线,保存手机存储的,LRU算法的

4.什么周期的管理,Fragment

你可能感兴趣的:(Glide图片加载框架设计)