Gilde源碼分析

with()過程

Glide的實現(xiàn)

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

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//不急著看咙鞍,會有回頭的時候
<R> Target<R> buildImageViewTarget(ImageView imageView, Class<R> transcodedClass) {
    return imageViewTargetFactory.buildTarget(imageView, transcodedClass);
}

public class ImageViewTargetFactory {
    //將ImageView包裝成一個GlideDrawableImageViewTarget對象
    //回到into過程看看這個包裝類的實現(xiàn)
    @SuppressWarnings("unchecked")
    public <Z> Target<Z> buildTarget(ImageView view, Class<Z> clazz) {
        return (Target<Z>) new GlideDrawableImageViewTarget(view);
    }
}

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//獲取一個Engine對象
//雖然實際上不是這樣實現(xiàn)的,但是是這么個意思
Engine getEngine() {
    if (engine == null) {
        engine = new Engine(memoryCache, diskCacheFactory, diskCacheService, sourceService);
    }
    return engine;
}


RequestManagerRetriever的實現(xiàn)

public class RequestManagerRetriever implements Handler.Callback {

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    public RequestManager get(FragmentActivity activity) {
        if (Util.isOnBackgroundThread()) {
            return get(activity.getApplicationContext());
        } else {
            assertNotDestroyed(activity);
            FragmentManager fm = activity.getSupportFragmentManager();
            return supportFragmentGet(activity, fm);
        }
    }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    RequestManager supportFragmentGet(Context context, FragmentManager fm) {
        //1.獲取一個SupportRequestManagerFragment對象
        SupportRequestManagerFragment current = getSupportRequestManagerFragment(fm);
        //2.通過Fragment獲取一個其中的RequestManager對象
        RequestManager requestManager = current.getRequestManager();
        if (requestManager == null) {
            //創(chuàng)建一個新的requestManager對象
            //注意current.getLifecycle()參數(shù)
            requestManager = new RequestManager(context, current.getLifecycle(), current.getRequestManagerTreeNode());
            current.setRequestManager(requestManager);
        }
        return requestManager;
    }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    //通過FragmentManager獲取SupportRequestManagerFragment對象
    SupportRequestManagerFragment getSupportRequestManagerFragment(final FragmentManager fm) {
        SupportRequestManagerFragment current = 
            (SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
        if (current == null) {
            current = pendingSupportRequestManagerFragments.get(fm);
            if (current == null) {
                current = new SupportRequestManagerFragment();
                //這是一個HashMap,用來起緩存作用
                pendingSupportRequestManagerFragments.put(fm, current);
                //commit到外部的Activity中去
                //注意是此時fragment的生命周期就和外部Activity的生命周期綁定了
                fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
                handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
            }
        }
        return current;
    }
}

SupportRequestManagerFragment的實現(xiàn)

public class SupportRequestManagerFragment extends Fragment {

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    //保存了一個RequestManager
    private RequestManager requestManager;
    //很明顯lifecycle是和生命周期有關智政,
    private final ActivityFragmentLifecycle lifecycle;
    
    public SupportRequestManagerFragment() {
        this(new ActivityFragmentLifecycle());
    }
    
    public SupportRequestManagerFragment(ActivityFragmentLifecycle lifecycle) {
        this.lifecycle = lifecycle;
    }

    public void setRequestManager(RequestManager requestManager) {
        this.requestManager = requestManager;
    }
 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    @Override
    public void onStart() {
        super.onStart();
        lifecycle.onStart();
    }

    @Override
    public void onStop() {
        super.onStop();
        lifecycle.onStop();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        lifecycle.onDestroy();
    }
}

ActivityFragmentLifecycle的實現(xiàn)

class ActivityFragmentLifecycle implements Lifecycle {

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    //LifecycleListener的集合阐斜,只有onStart(),onStop(),onDestroy()三個方法
    private final Set<LifecycleListener> lifecycleListeners =
            Collections.newSetFromMap(new WeakHashMap<LifecycleListener, Boolean>());
            
    private boolean isStarted;
    private boolean isDestroyed;

    //Lifecycle只有這一個需要實現(xiàn)的接口
    @Override
    public void addListener(LifecycleListener listener) {
        lifecycleListeners.add(listener);

        if (isDestroyed) {
            listener.onDestroy();
        } else if (isStarted) {
            listener.onStart();
        } else {
            listener.onStop();
        }
    }

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    //這里做的事顯而易見
    void onStart() {
        isStarted = true;
        for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
            lifecycleListener.onStart();
        }
    }

    void onStop() {
        isStarted = false;
        for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
            lifecycleListener.onStop();
        }
    }

    void onDestroy() {
        isDestroyed = true;
        for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
            lifecycleListener.onDestroy();
        }
    }
}

RequestManager的實現(xiàn)

public class RequestManager implements LifecycleListener {

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    //在創(chuàng)建RequestManager的同時也創(chuàng)建了一個RequestTracker
    private final RequestTracker requestTracker;

    public RequestManager(Context context, Lifecycle lifecycle, RequestManagerTreeNode treeNode) {
        this(context, lifecycle, treeNode, new RequestTracker(), new ConnectivityMonitorFactory());
    }

    //構造方法中的lifecycle就是SupportRequestManagerFragment的lifecycle
    RequestManager(Context context, final Lifecycle lifecycle, RequestManagerTreeNode treeNode,
            RequestTracker requestTracker, ConnectivityMonitorFactory factory) {
            
            this.requestTracker = requestTracker;
            //這個過程就是將RequestManager和SupportRequestManagerFragment生命周期綁定在一起
            lifecycle.addListener(this);
    }
    
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

    @Override
    public void onStart() {
        requestTracker.resumeRequests();
    }
    
    @Override
    public void onStop() {
        requestTracker.pauseRequests();
    }
    
    @Override
    public void onDestroy() {
        requestTracker.clearRequests();
    }

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  
  //load過程開始的地方
  public DrawableTypeRequest<String> load(String string) {
    return (DrawableTypeRequest<String>) fromString().load(string);
  }  
  
  public DrawableTypeRequest<String> fromString() {
    return loadGeneric(String.class);
  }
  
  private <T> DrawableTypeRequest<T> loadGeneric(Class<T> modelClass) {
        //重點關注這兩個ModelLoader對象
        //將String轉換為數(shù)據(jù)流 -> StreamStringLoader
        ModelLoader<T, InputStream> streamModelLoader = 
                        Glide.buildStreamModelLoader(modelClass, context);
        //將String轉換為文件類型 -> FileDescriptorStringLoader 
        ModelLoader<T, ParcelFileDescriptor> fileDescriptorModelLoader =
                        Glide.buildFileDescriptorModelLoader(modelClass, context);
                        
        //兩個modelLoader以及requestTracker都被封裝到DrawableTypeRequest對象中
        return optionsApplier.apply(
                new DrawableTypeRequest<T>(modelClass, 
                streamModelLoader, 
                fileDescriptorModelLoader, 
                context, glide, requestTracker, lifecycle, optionsApplier));
    }
}

RequestTracker的實現(xiàn)


public class RequestTracker {
    
    private final Set<Request> requests = Collections.newSetFromMap(new WeakHashMap<Request, Boolean>());
   
    @SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
    private final List<Request> pendingRequests = new ArrayList<Request>();

    private boolean isPaused;

    //這里就是執(zhí)行請求的地方
    public void runRequest(Request request) {
        requests.add(request);
        if (!isPaused) {
            request.begin();
        } else {
            pendingRequests.add(request);
        }
    }
    
    public void removeRequest(Request request) {
        requests.remove(request);
        pendingRequests.remove(request);
    }

    public boolean isPaused() {
        return isPaused;
    }

    public void pauseRequests() {
        isPaused = true;
        for (Request request : Util.getSnapshot(requests)) {
            if (request.isRunning()) {
                request.pause();
                pendingRequests.add(request);
            }
        }
    }

    public void resumeRequests() {
        isPaused = false;
        for (Request request : Util.getSnapshot(requests)) {
            if (!request.isComplete() && !request.isCancelled() && !request.isRunning()) {
                request.begin();
            }
        }
        pendingRequests.clear();
    }

    public void clearRequests() {
        for (Request request : Util.getSnapshot(requests)) {
            request.clear();
        }
        pendingRequests.clear();
    }

    public void restartRequests() {
        for (Request request : Util.getSnapshot(requests)) {
            if (!request.isComplete() && !request.isCancelled()) {
                // Ensure the request will be restarted in onResume.
                request.pause();
                if (!isPaused) {
                    request.begin();
                } else {
                    pendingRequests.add(request);
                }
            }
        }
    }
}

load()過程

ModelLoader<T,Y>接口

//一個工廠接口模型,將任意復雜的數(shù)據(jù)模型轉化為一個具體的數(shù)據(jù)類型可以被DataFatcher使用
//T:原始煤杀。  Y:轉化后眷蜈。
//兩個目的
//1、將一個具體的model轉換為可以被解碼為資源的數(shù)據(jù)類型
//2沈自、允許一個model結合View的尺寸大小去獲取具體的資源
public interface ModelLoader<T, Y> {
    DataFetcher<Y> getResourceFetcher(T model, int width, int height);
}

DataFetcher<T>接口

public interface DataFetcher<T> {
    //很明顯是用來加載數(shù)據(jù)的
    T loadData(Priority priority) throws Exception;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    //不用關注
    void cleanup();
    String getId();
    void cancel();
}

DrawableTypeRequest實現(xiàn)

//是一個建造者的類酌儒,用來創(chuàng)建請求
//有多重繼承關系,為了簡潔將父類方法的實現(xiàn)直接寫到下面類中
public class DrawableTypeRequest<ModelType> 
                extends DrawableRequestBuilder<ModelType> 
                implements DownloadOptions {
    //例如幾個常用參數(shù)          
    private Drawable placeholderDrawable;
    private Drawable errorPlaceholder;
    private Priority priority = null;
    private boolean isCacheable = true;
    
    //就是很簡單的把參數(shù)傳進去
    //可以看出這是一個建造者類枯途,也就是說可以在里面設置很多參數(shù)
    public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> load(ModelType model) {
        this.model = model;
        isModelSet = true;
        return this;
    }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    //into()開始的地方忌怎,最復雜的過程從這里開始
    public Target<TranscodeType> into(ImageView view) {
        //先去看看buildImageViewTarget()做了些什么
        return into(glide.buildImageViewTarget(view, transcodeClass));
    }
    
    public <Y extends Target<TranscodeType>> Y into(Y target) {
    
        Request previous = target.getRequest();
        //如果之前有Request就刪掉
        if (previous != null) {
            previous.clear();
            requestTracker.removeRequest(previous);
            previous.recycle();
        }
        //創(chuàng)建Request
        Request request = buildRequest(target);
        //將Request放到包裝類中去
        target.setRequest(request);
        //這個更有意思,也很奇怪酪夷,為什么呢榴啸??晚岭?鸥印???库说?狂鞋??潜的?骚揍??啰挪?疏咐??
        //這個lifecycle也就是最最上面的那個Fragment中的lifecycle脐供,其實就是個集合
        lifecycle.addListener(target);
        //開始執(zhí)行這個Resquest
        requestTracker.runRequest(request);
    
        return target;
    }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    //創(chuàng)建Request
    private Request buildRequest(Target<TranscodeType> target) {
        if (priority == null) {
            priority = Priority.NORMAL;
        }
        return buildRequestRecursive(target, null);
    }
    
    private Request buildRequestRecursive(Target<TranscodeType> target, ThumbnailRequestCoordinator parentCoordinator) {
        //雖然這里進行了很多操作浑塞,但是最后還是調(diào)用obtainRequest去創(chuàng)建Request
       return obtainRequest(target, sizeMultiplier, priority, parentCoordinator);
    }
    
    //這個有點意思,居然傳入了這么多參數(shù)政己,而最后真的返回了一個Request
    //沒錯酌壕,這里就是建造者模式建造的過程,這些就是我們當時設置的參數(shù)
    //這個時候歇由,我們當然要去看看GenericRequest的實現(xiàn)卵牍,具體在下面
    private Request obtainRequest(Target<TranscodeType> target, float sizeMultiplier, Priority priority,
            RequestCoordinator requestCoordinator) {
        return GenericRequest.obtain(
                loadProvider,
                model,
                signature,
                context,
                priority,
                target,
                sizeMultiplier,
                placeholderDrawable,
                placeholderId,
                errorPlaceholder,
                errorId,
                fallbackDrawable,
                fallbackResource,
                requestListener,
                requestCoordinator,
                glide.getEngine(),
                transformation,
                transcodeClass,
                isCacheable,
                animationFactory,
                overrideWidth,
                overrideHeight,
                diskCacheStrategy);
    }


>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
DrawableTypeRequest(Class<ModelType> modelClass, ModelLoader<ModelType, InputStream> streamModelLoader,
            ModelLoader<ModelType, ParcelFileDescriptor> fileDescriptorModelLoader, Context context, Glide glide,
            RequestTracker requestTracker, Lifecycle lifecycle, RequestManager.OptionsApplier optionsApplier) {
        super(context, modelClass,
                    //注意這里生成了一個LoadProvider
                buildProvider(glide, streamModelLoader, fileDescriptorModelLoader, GifBitmapWrapper.class, GlideDrawable.class, null),
                glide, requestTracker, lifecycle);
        this.streamModelLoader = streamModelLoader;
        this.fileDescriptorModelLoader = fileDescriptorModelLoader;
        this.optionsApplier = optionsApplier;
    }
}

into()過程

GlideDrawableImageViewTarget的實現(xiàn)

//為了簡潔,將父類的屬性沦泌、方法直接放到子類中
//這類最后是實現(xiàn)了lifecycle的接口
public class GlideDrawableImageViewTarget extends ImageViewTarget<GlideDrawable> {
    
    //這個類糊昙,很明顯和Drawable有關系,很可能就是就是我們最后所需要的圖片資源
    private GlideDrawable resource;
    //這個屬性存儲著目標的ImageView
    protected final T view;
    //這里還封裝了request請求谢谦,這就有點意思了
    private Request request;

    public GlideDrawableImageViewTarget(ImageView view) {
        this(view, GlideDrawable.LOOP_FOREVER);
    }

    public GlideDrawableImageViewTarget(ImageView view, int maxLoopCount) {
        super(view);
    }
    
    public ImageViewTarget(ImageView view) {
        super(view);
    }
    
    public ViewTarget(T view) {
        if (view == null) {
            throw new NullPointerException("View must not be null!");
        }
        this.view = view;
    }
}

GenericRequest的實現(xiàn)

//1.既然是final修飾释牺,也就是說這就是Request的實現(xiàn)了,不會有其他類繼承它回挽,再做一下騷操作
//2.需要注意這兩個接口SizeReadyCallback,ResourceCallback,會有大用
public final class GenericRequest<A, T, Z, R> implements Request, 
    SizeReadyCallback,ResourceCallback {

    //請求開始的地方
    @Override
    public void begin() {
        //省略一些代碼
        onSizeReady(overrideWidth, overrideHeight);
    }
    
    @Override
    public void onSizeReady(int width, int height) {
        
        status = Status.RUNNING;

        width = Math.round(sizeMultiplier * width);
        height = Math.round(sizeMultiplier * height);

        ModelLoader<A, T> modelLoader = loadProvider.getModelLoader();
        final DataFetcher<T> dataFetcher = modelLoader.getResourceFetcher(model, width, height);

        loadedFromMemoryCache = true;
        loadStatus = engine.load(signature, width, height, 
        dataFetcher, loadProvider, transformation, transcoder,
                priority, isMemoryCacheable, diskCacheStrategy, this);
    }
    
    private void onResourceReady(Resource<?> resource, R result) {
        // We must call isFirstReadyResource before setting status.
        boolean isFirstResource = isFirstReadyResource();
        status = Status.COMPLETE;
        this.resource = resource;

        if (requestListener == null || !requestListener.onResourceReady(result, model, target, loadedFromMemoryCache,
                isFirstResource)) {
            //這個target就是ImageView生成的包裝類
            //在onResourceReady()中就是把圖片資源set到ImageView中去
            target.onResourceReady(result, animation);
        }

    }   

}

Engine的實現(xiàn)

public class Engine implements EngineJobListener,
        MemoryCache.ResourceRemovedListener,
        EngineResource.ResourceListener {
        
    public <T, Z, R> LoadStatus load(Key signature, int width, int height, DataFetcher<T> fetcher,
            DataLoadProvider<T, Z> loadProvider, Transformation<Z> transformation, ResourceTranscoder<Z, R> transcoder,
            Priority priority, boolean isMemoryCacheable, DiskCacheStrategy diskCacheStrategy, ResourceCallback cb) {
       

        final String id = fetcher.getId();
        EngineKey key = keyFactory.buildKey(id, signature, width, height, loadProvider.getCacheDecoder(),
                loadProvider.getSourceDecoder(), transformation, loadProvider.getEncoder(),
                transcoder, loadProvider.getSourceEncoder());

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

        EngineJob current = jobs.get(key);
        if (current != null) {
            current.addCallback(cb);
            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                logWithTimeAndKey("Added to existing load", startTime, key);
            }
            return new LoadStatus(cb, current);
        }
        
        //從這里開始看
        //EngineJob: 通過添加和刪除加載的回調(diào)并在加載完成時通知回調(diào)來管理加載的類没咙。
        EngineJob engineJob = engineJobFactory.build(key, isMemoryCacheable);
        //DecodeJob: 負責解碼資源和申請轉碼的類。
        DecodeJob<T, Z, R> decodeJob = new DecodeJob<T, Z, R>(key, 
                    width, height, fetcher, loadProvider, transformation,
                transcoder, diskCacheProvider, diskCacheStrategy, priority);
        //注意千劈,在這里engineJob和decodeJob都被傳進去了
        EngineRunnable runnable = new EngineRunnable(engineJob, decodeJob, priority);
        jobs.put(key, engineJob);
        engineJob.addCallback(cb);
        engineJob.start(runnable);

        if (Log.isLoggable(TAG, Log.VERBOSE)) {
            logWithTimeAndKey("Started new load", startTime, key);
        }
        return new LoadStatus(cb, engineJob);
    }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    //圖片資源獲取祭刚、緩存、解碼之后的回調(diào)
    @Override
    public void onResourceReady(final Resource<?> resource) {
        this.resource = resource;
        MAIN_THREAD_HANDLER.obtainMessage(MSG_COMPLETE, this).sendToTarget();
    }
    
    private void handleResultOnMainThread() {
        engineResource = engineResourceFactory.build(resource, isCacheable);
        hasResource = true;
        //資源引用數(shù)
        engineResource.acquire();
        listener.onEngineJobComplete(key, engineResource);

        for (ResourceCallback cb : cbs) {
            if (!isInIgnoredCallbacks(cb)) {
                engineResource.acquire();
                cb.onResourceReady(engineResource);
            }
        }
        //釋放資源
        engineResource.release();
    }
}

EngineRunnable的實現(xiàn)

class EngineRunnable implements Runnable, Prioritized {
    
    private final DecodeJob<?, ?, ?> decodeJob;

    @Override
    public void run() {
        //從這里開始就已經(jīng)在子線程工作了
        Exception exception = null;
        Resource<?> resource = null;
        //這個resource就是最后解碼得到的結果
        resource = decode();
        //這里是處理結果的步驟
        if (resource == null) {
            onLoadFailed(exception);
        } else {
            onLoadComplete(resource);
        }
    }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    private Resource<?> decode() throws Exception {
        if (isDecodingFromCache()) {
            //從緩存中讀取墙牌,這里的緩存指的是磁盤的緩存
            return decodeFromCache();
        } else {
            //從源地址讀取
            return decodeFromSource();
        }
    }
    
    //從源地址讀取
    private Resource<?> decodeFromSource() throws Exception {
        return decodeJob.decodeFromSource();
    }

}

DecodeJob的實現(xiàn)

class DecodeJob<A, T, Z> {

    public Resource<Z> decodeFromSource() throws Exception {
    
        Resource<T> decoded = decodeSource();
        
        return transformEncodeAndTranscode(decoded);
    }
    
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    private Resource<T> decodeSource() throws Exception {
        Resource<T> decoded = null;
        //讀取數(shù)據(jù),這里已經(jīng)進行了網(wǎng)路請求涡驮,拿到了數(shù)據(jù)
        //具體實現(xiàn)暫時不關注
        //這個fetcher早就在之前創(chuàng)建好了,一步步傳遞過來的
        final A data = fetcher.loadData(priority);
        decoded = decodeFromSourceData(data);
        return decoded;
    }

    private Resource<T> decodeFromSourceData(A data) throws IOException {
        final Resource<T> decoded;
        //省略了相當一部分代碼
        decoded = cacheAndDecodeSourceData(data);
        return decoded;
    }
    
    //在這里通過key保存到了磁盤中
    private Resource<T> cacheAndDecodeSourceData(A data) throws IOException {
        SourceWriter<A> writer = new SourceWriter<A>(loadProvider.getSourceEncoder(), data);
        diskCacheProvider.getDiskCache().put(resultKey.getOriginalKey(), writer);
        Resource<T> result = loadFromCache(resultKey.getOriginalKey());
        return result;
    }  
    
    private Resource<T> loadFromCache(Key key) throws IOException {
        File cacheFile = diskCacheProvider.getDiskCache().get(key);
        if (cacheFile == null) {
            return null;
        }

        Resource<T> result = null;
        try {
            result = loadProvider.getCacheDecoder().decode(cacheFile, width, height);
        } finally {
            if (result == null) {
                diskCacheProvider.getDiskCache().delete(key);
            }
        }
        return result;
    } 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    
}

緩存機制

生成緩存的key

//傳入這么多參數(shù)喜滨,其實最后是重寫了equals()和HashCode
//對于Url來說id就默認是當前的url
final String id = fetcher.getId();
EngineKey key = keyFactory.buildKey(id, signature, width, height, loadProvider.getCacheDecoder(),
                loadProvider.getSourceDecoder(), transformation, loadProvider.getEncoder(),
                transcoder, loadProvider.getSourceEncoder());

EngineResource<?> cached = loadFromCache(key, isMemoryCacheable);
if (cached != null) {
    cb.onResourceReady(cached);
    return null;
}
EngineResource<?> active = loadFromActiveResources(key, isMemoryCacheable);
if (active != null) {
    cb.onResourceReady(active);
    return null;
}

內(nèi)存緩存

1捉捅、LruCache算法(Least Recently Used)
2、弱引用機制

通過兩個方法來獲得內(nèi)存緩存

  • loadFromCache ------LruCache算法
  • loadFromActiveSource------弱引用
//看一看LoadFromCache的執(zhí)行過程
private EngineResource<?> loadFromCache(Key key, boolean isMemoryCacheable) {
    if (!isMemoryCacheable) {
        return null;
    }
    EngineResource<?> cached = getEngineResourceFromCache(key);
    if (cached != null) {
        //這個方法就是++操作鸿市,表示這個資源被引用數(shù)
        cached.acquire();
        activeResources.put(key, new ResourceWeakReference(key, cached, getReferenceQueue()));
    }
    return cached;
}

@SuppressWarnings("unchecked")
private EngineResource<?> getEngineResourceFromCache(Key key) {
    //這個cache就是實現(xiàn)了LruCache算法
    Resource<?> cached = cache.remove(key);
    final EngineResource result;
    if (cached == null) {
        result = null;
    } else if (cached instanceof EngineResource) {
        result = (EngineResource) cached;
    } else {
        result = new EngineResource(cached, true /*isCacheable*/);
    }
    return result;
}
//通過弱引用獲取資源锯梁,
private EngineResource<?> loadFromActiveResources(Key key, boolean isMemoryCacheable) {
    if (!isMemoryCacheable) {
        return null;
    }
    EngineResource<?> active = null;
    //activeResources就是一個HashMap即碗,value就是對資源的弱引用
    WeakReference<EngineResource<?>> activeRef = activeResources.get(key);
    if (activeRef != null) {
        active = activeRef.get();
        if (active != null) {
            //這個方法就是++操作焰情,表示這個資源被引用數(shù)
            //同時陌凳,對應的release()方法就是做了--操作
            active.acquire();
        } else {
            activeResources.remove(key);
        }
    }
    return active;
}

磁盤緩存

也采用LruCache策略,Glide自己實現(xiàn)的DiskLruCache

//這個已經(jīng)是在子線程的Runnable中
private Resource<?> decode() throws Exception {
    if (isDecodingFromCache()) {
        return decodeFromCache();
    } else {
        return decodeFromSource();
    }
}

private Resource<?> decodeFromCache() throws Exception {
    Resource<?> result = null
    result = decodeJob.decodeResultFromCache();
    if (result == null) {
        result = decodeJob.decodeSourceFromCache();
    }
    return result;
}

public Resource<Z> decodeResultFromCache() throws Exception {
    if (!diskCacheStrategy.cacheResult()) {
        return null;
    }
    Resource<T> transformed = loadFromCache(resultKey);
    Resource<Z> result = transcode(transformed);
    return result;
}

public Resource<Z> decodeSourceFromCache() throws Exception {
    if (!diskCacheStrategy.cacheSource()) {
        return null;
    }
    Resource<T> decoded = loadFromCache(resultKey.getOriginalKey())
    return transformEncodeAndTranscode(decoded);
}

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

private Resource<T> loadFromCache(Key key) throws IOException {
    File cacheFile = diskCacheProvider.getDiskCache().get(key);
    if (cacheFile == null) {
        return null;
    }
    Resource<T> result = null;
    try {
        result = loadProvider.getCacheDecoder().decode(cacheFile, width, height);
    } finally {
        if (result == null) {
            diskCacheProvider.getDiskCache().delete(key);
        }
    }
    return result;
}
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末内舟,一起剝皮案震驚了整個濱河市合敦,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌验游,老刑警劉巖充岛,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異耕蝉,居然都是意外死亡崔梗,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進店門垒在,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蒜魄,“玉大人,你說我怎么就攤上這事场躯√肝” “怎么了?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵踢关,是天一觀的道長伞鲫。 經(jīng)常有香客問我,道長签舞,這世上最難降的妖魔是什么秕脓? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮儒搭,結果婚禮上撒会,老公的妹妹穿的比我還像新娘。我一直安慰自己师妙,他們只是感情好诵肛,可當我...
    茶點故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著默穴,像睡著了一般怔檩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蓄诽,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天薛训,我揣著相機與錄音,去河邊找鬼仑氛。 笑死乙埃,一個胖子當著我的面吹牛闸英,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播介袜,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼甫何,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了遇伞?” 一聲冷哼從身側響起辙喂,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎鸠珠,沒想到半個月后巍耗,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡渐排,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年炬太,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片驯耻。...
    茶點故事閱讀 39,769評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡亲族,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出吓歇,到底是詐尸還是另有隱情孽水,我是刑警寧澤,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布城看,位于F島的核電站女气,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏测柠。R本人自食惡果不足惜炼鞠,卻給世界環(huán)境...
    茶點故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望轰胁。 院中可真熱鬧谒主,春花似錦、人聲如沸赃阀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽榛斯。三九已至观游,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間驮俗,已是汗流浹背懂缕。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留王凑,地道東北人搪柑。 一個月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓聋丝,卻偏偏與公主長得像,于是被迫代替她去往敵國和親工碾。 傳聞我的和親對象是個殘疾皇子弱睦,可洞房花燭夜當晚...
    茶點故事閱讀 44,678評論 2 354

推薦閱讀更多精彩內(nèi)容