超详细的Glide源码解析

1. 简单使用


Glide.with(this).load(url)
                .placeholder(R.mipmap.ic_launcher)
                .error(R.mipmap.ic_launcher)
                .centerCrop()
                .skipMemoryCache(true)
                .diskCacheStrategy(DiskCacheStrategy.RESULT)
                .priority(Priority.HIGH)
                .into(mIvMn);

2. with方法

参数类型:Activity,Context,Fragment,ApplicationContext(本质上也是Context) 类型决定生命周期

2.1 with方法


with方法

public static RequestManager with(Context context) {
    RequestManagerRetriever retriever = RequestManagerRetriever.get();
    return retriever.get(context);
}

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

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

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public static RequestManager with(android.app.Fragment fragment) {
    RequestManagerRetriever retriever = RequestManagerRetriever.get();
    return retriever.get(fragment);
}

public static RequestManager with(Fragment fragment) {
    RequestManagerRetriever retriever = RequestManagerRetriever.get();
    return retriever.get(fragment);
}

这几个重载方法最终都是调用RequestManagerRetriever.get()方法获取RequestManagerRetriever对象,然后通过这个对象获取RequestManager对象

2.2 RequestManagerRetriever对象的get方法


public RequestManager get(Context context) {
    if (context == null) {
        throw new IllegalArgumentException("You cannot start a load on a null Context");
    } else if (Util.isOnMainThread() && !(context instanceof Application)) {
//判断当前线程是不是主线程 并且context是不是Application 
        //分别转化为相应的Context对象
        if (context instanceof FragmentActivity) {
            return get((FragmentActivity) context);
        } else if (context instanceof Activity) {
            return get((Activity) context);
        } else if (context instanceof ContextWrapper) {
            return get(((ContextWrapper) context).getBaseContext());
        }
    }

    return getApplicationManager(context);
}

private RequestManager getApplicationManager(Context context) {
    if (applicationManager == null) {
        synchronized (this) {
            if (applicationManager == null) {
                applicationManager = new RequestManager(context.getApplicationContext(),
                        new ApplicationLifecycle(), new EmptyRequestManagerTreeNode());
            }
        }
    }

    return applicationManager;
}


@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public RequestManager get(Activity activity) {
    if (Util.isOnBackgroundThread() || Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
        return get(activity.getApplicationContext());
    } else {
        assertNotDestroyed(activity);
        android.app.FragmentManager fm = activity.getFragmentManager();
        return fragmentGet(activity, fm);
    }
}

1) get方法首先会判断传入的Context的类型,如果传入的Context类型是Application或者是在子线程加载的图片,这会通过getApplicationManager方法单例形式创建一个RequestManager对象。

2) 否则会调用fragmentGet方法,传入Context对象和FragmentManager对象。

2.3 fragmentGet方法


@TargetApi(Build.VERSION_CODES.HONEYCOMB)
RequestManager fragmentGet(Context context, android.app.FragmentManager fm) {
    RequestManagerFragment current = getRequestManagerFragment(fm);
    RequestManager requestManager = current.getRequestManager();
    if (requestManager == null) {
        requestManager = new RequestManager(context, current.getLifecycle(), current.getRequestManagerTreeNode());
        current.setRequestManager(requestManager);
    }
    return requestManager;
}


@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
RequestManagerFragment getRequestManagerFragment(final android.app.FragmentManager fm) {
    RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
    if (current == null) {
        current = pendingRequestManagerFragments.get(fm);
        if (current == null) {
            current = new RequestManagerFragment();
            pendingRequestManagerFragments.put(fm, current);
            fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
            handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
        }
    }
    return current;
}

1) 通过getRequestManagerFragment创建一个没有UI界面的fragment,通过这个fragment获取RequestManager对象。

2) 如果上面获取的对象为空,就直接创建一个RequestManager对象,传入上下文,LifecycleListener对象(这是用来监听activity生命周期的接口),还有一个不知名的对象。

3) 当前fragment绑定RequestManager对象,glide是无法知道activity生命周期的,所以这里添加了一个没有UI界面的fragment来监听Activity的生命周期,这样设计很巧妙。

4) getRequestManagerFragment方法主要是去获取fragment对象,如果对象不存在,就创建一个新的对象,同时添加到activity中,并且通过Handler发送一条消息,在handlemessage中移除当前fm对象。

2.4 RequestManagerFragment类

RequestManagerFragment类

public RequestManagerFragment() {
    this(new ActivityFragmentLifecycle());
}

// For testing only.
@SuppressLint("ValidFragment")
RequestManagerFragment(ActivityFragmentLifecycle lifecycle) {
    this.lifecycle = lifecycle;
}

ActivityFragmentLifecycle getLifecycle() {
    return lifecycle;
}

@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对象,这个对象就是监听fragment生命周期的,从fragment的生命周期方法中可以很明确看出来。

2.5 ActivityFragmentLifecycle类

ActivityFragmentLifecycle类

class ActivityFragmentLifecycle implements Lifecycle {


        @Override
    public void addListener(LifecycleListener listener) {
        lifecycleListeners.add(listener);

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


public interface Lifecycle {
    void addListener(LifecycleListener listener);
}

public interface LifecycleListener {

    void onStart();

    void onStop();

    void onDestroy();
}

可以看出LifecycleListener接口才是定义监听fragment生命周期的类,上面的类都不过实现了这个接口类而已。

2.6 小结

width方法最终目的都是通过RequestManagerRetriever对象的get方法获取RequestManager对象,传入参数主要分Application类型和非Application类型

1) 如果with方法传入的是Application,会通过调用getApplicationManager()来获取一个RequestManager对象,不需要处理生命周期,因为Application对象的生命周期就是应用程序的生命周期

2) 如果with方法传入的不是Application类型,最终流程都是一样,那就是会向当前的Activity当中添加一个隐藏的Fragment,app包下的fragment会调用fragmentGet方法创建隐藏fragment,v4包下的fragment会调用supportFragmentGet方法创建fragment,都会返回RequestManager对象,创建隐藏fragment的目的是Glide需要知道加载的生命周期,可是Glide并没有办法知道Activity的生命周期,于是Glide就使用了添加隐藏Fragment的这种小技巧,因为Fragment的生命周期和Activity是同步的,如果Activity被销毁了,Fragment是可以监听到的,这样Glide就可以捕获这个事件并停止图片加载了。

3)如果我们是在非主线程当中使用的Glide,那么不管你是传入的Activity还是Fragment,都会被强制当成Application来处理,调用getApplicationManager()来获取RequestManager对象

3. load方法

参数类型:String,File,byte[],URL,图片资源ID,Uri,我这里只看参数类型为String类型的,这些方法都会返回DrawableTypeRequest对象。

3.1 load方法

public DrawableTypeRequest load(String string) {
    return (DrawableTypeRequest) fromString().load(string);
}


public DrawableTypeRequest fromString() {
    return loadGeneric(String.class);
}


private  DrawableTypeRequest loadGeneric(Class modelClass) {
    ModelLoader streamModelLoader = Glide.buildStreamModelLoader(modelClass, context);
    ModelLoader fileDescriptorModelLoader =
            Glide.buildFileDescriptorModelLoader(modelClass, context);
    if (modelClass != null && streamModelLoader == null && fileDescriptorModelLoader == null) {
        throw new IllegalArgumentException("Unknown type " + modelClass + ". You must provide a Model of a type for"
                + " which there is a registered ModelLoader, if you are using a custom model, you must first call"
                + " Glide#register with a ModelLoaderFactory for your custom model class");
    }

    return optionsApplier.apply(
            new DrawableTypeRequest(modelClass, streamModelLoader, fileDescriptorModelLoader, context,
                    glide, requestTracker, lifecycle, optionsApplier));
}

load内部调用了fromString方法,fromString方法调用了loadGeneric方法,
loadGeneric()方法也没几行代码,这里分别调用了Glide.buildStreamModelLoader()方法和Glide.buildFileDescriptorModelLoader()方法来获得ModelLoader对象。
ModelLoader对象是用于加载图片的,而我们给load()方法传入不同类型的参数,这里也会得到不同的ModelLoader对象。

3.2 DrawableTypeRequest类

load方法都会返回这个DrawableTypeRequest类,这里面两个重要方法是asBitmap方法和asGif方法,asBitmap方法会创建一个BitmapTypeRequest对象,同时会返回BitmapTypeRequest类型,这个方法会将图片强制转换为静态图片,asGif方法会创建一个GifTypeRequest对象,同时会返回GifTypeRequest类型,这个方法会强制将图片转换为动态图片,如果图片本身是静态图片,则图片加载会失败。

3.3 DrawableRequestBuilder类

它是DrawableTypeRequest的父类,这里面提供了glide加载图片过程的很多方法,比如animate,centerCrop,crossFade,error,fitCenter,placeholder,skipMemoryCache,priority等等…


public class DrawableRequestBuilder<ModelType>
        extends GenericRequestBuilder<ModelType, ImageVideoWrapper, GifBitmapWrapper, GlideDrawable>
        implements BitmapOptions, DrawableOptions {

    DrawableRequestBuilder(Context context, Class modelClass,
            LoadProvider loadProvider, Glide glide,
            RequestTracker requestTracker, Lifecycle lifecycle) {
        super(context, modelClass, loadProvider, GlideDrawable.class, glide, requestTracker, lifecycle);
        // Default to animating.
        crossFade();
    }


    //图片的一种显示格式
    @SuppressWarnings("unchecked")
    public DrawableRequestBuilder centerCrop() {
        return transform(glide.getDrawableCenterCrop());
    }

    //图片的一种显示格式
    @SuppressWarnings("unchecked")
    public DrawableRequestBuilder fitCenter() {
        return transform(glide.getDrawableFitCenter());
    }

    //图片显示设置渐变时间
    public DrawableRequestBuilder crossFade(int duration) {
        super.animate(new DrawableCrossFadeFactory(duration));
        return this;
    }

    //磁盘缓存策略
     @Override
    public DrawableRequestBuilder diskCacheStrategy(DiskCacheStrategy strategy) {
        super.diskCacheStrategy(strategy);
        return this;
    }

    //是否跳过内存缓存
    @Override
    public DrawableRequestBuilder skipMemoryCache(boolean skip) {
        super.skipMemoryCache(skip);
        return this;
    }

    //设置图片尺寸
     @Override
    public DrawableRequestBuilder override(int width, int height) {
        super.override(width, height);
        return this;
    }

    //设置图片加载优先级
    @Override
    public DrawableRequestBuilder priority(Priority priority) {
        super.priority(priority);
        return this;
    }
}

3.4 GenericRequestBuilder类:DrawableRequestBuilder的父类,这里面提供了绝大部分glide加载图片过程中的方法,它的子类都是实现了这个父类。

一些重要参数
protected final RequestTracker requestTracker;
protected final Lifecycle lifecycle; 
private int placeholderId;
   private int errorId;
private Drawable placeholderDrawable;
   private Drawable errorPlaceholder;
   private Priority priority = null;
   private boolean isCacheable = true;
private int overrideHeight = -1;
   private int overrideWidth = -1;

构造方法:

GenericRequestBuilder(LoadProvider loadProvider,
       Class transcodeClass, GenericRequestBuilder other) {
       this(other.context, other.modelClass, loadProvider, transcodeClass, other.glide, other.requestTracker,
               other.lifecycle);
       this.model = other.model;
       this.isModelSet = other.isModelSet;
       this.signature = other.signature;
       this.diskCacheStrategy = other.diskCacheStrategy;
       this.isCacheable = other.isCacheable;
}

GenericRequestBuilder(Context context, Class modelClass,
        LoadProvider loadProvider,
        Class transcodeClass, Glide glide, RequestTracker requestTracker, Lifecycle lifecycle) {
    this.context = context;
    this.modelClass = modelClass;
    this.transcodeClass = transcodeClass;
    this.glide = glide;
    this.requestTracker = requestTracker;
    this.lifecycle = lifecycle;
    this.loadProvider = loadProvider != null
            ? new ChildLoadProvider(loadProvider) : null;

    if (context == null) {
        throw new NullPointerException("Context can't be null");
    }
    if (modelClass != null && loadProvider == null) {
        throw new NullPointerException("LoadProvider must not be null");
    }
}

4. into方法

4.1 into方法

into(ImageView  imageView)方法:

@Override
public Target into(ImageView view) {
    return super.into(view);
}

调用父类GenericRequestBuilder的into方法
public Target into(ImageView view) {
//断言是不是在主线程 因为ui更新操作在主线程
    Util.assertMainThread();
    if (view == null) {
        throw new IllegalArgumentException("You must pass in a non null View");
    }

    if (!isTransformationSet && view.getScaleType() != null) {
        switch (view.getScaleType()) {
            case CENTER_CROP:
                applyCenterCrop();
                break;
            case FIT_CENTER:
            case FIT_START:
            case FIT_END:
                applyFitCenter();
                break;
            //$CASES-OMITTED$
            default:
                // Do nothing.
        }
    }

    return into(glide.buildImageViewTarget(view, transcodeClass));
}

into方法最终会调用into(Target target)方法返回一个target对象,通过glide.buildImageViewTarget(view, transcodeClass)创建一个target对象

4.2 buildImageViewTarget方法

 Target buildImageViewTarget(ImageView imageView, Class<R> transcodedClass) {
    return imageViewTargetFactory.buildTarget(imageView, transcodedClass);
}


@SuppressWarnings("unchecked")
public  Target buildTarget(ImageView view, Class<Z> clazz) {
    if (GlideDrawable.class.isAssignableFrom(clazz)) {
        return (Target) new GlideDrawableImageViewTarget(view);
    } else if (Bitmap.class.equals(clazz)) {
        return (Target) new BitmapImageViewTarget(view);
    } else if (Drawable.class.isAssignableFrom(clazz)) {
        return (Target) new DrawableImageViewTarget(view);
    } else {
        throw new IllegalArgumentException("Unhandled class: " + clazz
                + ", try .as*(Class).transcode(ResourceTranscoder)");
    }
}

创建target对象主要分两种,如果你在使用Glide加载图片的时候调用了asBitmap()方法,那么这里就会构建出BitmapImageViewTarget对象,返回BitmapImageViewTarget对象,否则返回GlideDrawableImageViewTarget对象。

4.3 into(Target target)方法

public > Y into(Y target) {
    Util.assertMainThread();
    if (target == null) {
        throw new IllegalArgumentException("You must pass in a non null Target");
    }
    if (!isModelSet) {
        throw new IllegalArgumentException("You must first set a model (try #load())");
    }

    Request previous = target.getRequest();

    if (previous != null) {
        previous.clear();
        requestTracker.removeRequest(previous);
        previous.recycle();
    }

    Request request = buildRequest(target);
    target.setRequest(request);
    lifecycle.addListener(target);
//RequestTracker类用于跟踪、取消和重新启动进程中、已完成和失败请求
 //执行请求
    requestTracker.runRequest(request);

    return target;
}

@Override
public void setRequest(Request request) {
    setTag(request);
}

这里首先还是检查是不是在主线程,因为更新ui的操作必须在主线程,这里首先会通过target对象获取request对象,然后清除之前的request对象,回收request对象,然后重新构建一个新的request对象,并且给这个target设置request对象,这其实就是好比listView加载图片时候给图片设置tag,防止图片错位问题,这里requestTracker.runRequest这个方法是执行这个请求。

4.4 recycle方法

@Override
public void recycle() {
    loadProvider = null;
    model = null;
    context = null;
    target = null;
    placeholderDrawable = null;
    errorDrawable = null;
    fallbackDrawable = null;
    requestListener = null;
    requestCoordinator = null;
    transformation = null;
    animationFactory = null;
    loadedFromMemoryCache = false;
    loadStatus = null;
    REQUEST_POOL.offer(this);
}

主要是对象置空,boolean值置为false

4.5 buildRequest方法:构建request对象

private Request buildRequest(Target target) {
    图片加载默认优先级是NORMAL
       if (priority == null) {
           priority = Priority.NORMAL;
       }
       return buildRequestRecursive(target, null);
   }


private Request buildRequestRecursive(Target target, ThumbnailRequestCoordinator parentCoordinator) {
       if (thumbnailRequestBuilder != null) {
           if (isThumbnailBuilt) {
               throw new IllegalStateException("You cannot use a request as both the main request and a thumbnail, "
                       + "consider using clone() on the request(s) passed to thumbnail()");
           }
           // Recursive case: contains a potentially recursive thumbnail request builder.
           if (thumbnailRequestBuilder.animationFactory.equals(NoAnimation.getFactory())) {
               thumbnailRequestBuilder.animationFactory = animationFactory;
           }

           if (thumbnailRequestBuilder.priority == null) {
               thumbnailRequestBuilder.priority = getThumbnailPriority();
           }

           if (Util.isValidDimensions(overrideWidth, overrideHeight)
                   && !Util.isValidDimensions(thumbnailRequestBuilder.overrideWidth,
                           thumbnailRequestBuilder.overrideHeight)) {
             thumbnailRequestBuilder.override(overrideWidth, overrideHeight);
           }

           ThumbnailRequestCoordinator coordinator = new ThumbnailRequestCoordinator(parentCoordinator);
           Request fullRequest = obtainRequest(target, sizeMultiplier, priority, coordinator);
           // Guard against infinite recursion.
           isThumbnailBuilt = true;
           // Recursively generate thumbnail requests.
           Request thumbRequest = thumbnailRequestBuilder.buildRequestRecursive(target, coordinator);
           isThumbnailBuilt = false;
           coordinator.setRequests(fullRequest, thumbRequest);
           return coordinator;
       } else if (thumbSizeMultiplier != null) {
           // Base case: thumbnail multiplier generates a thumbnail request, but cannot recurse.
           ThumbnailRequestCoordinator coordinator = new ThumbnailRequestCoordinator(parentCoordinator);
           Request fullRequest = obtainRequest(target, sizeMultiplier, priority, coordinator);
           Request thumbnailRequest = obtainRequest(target, thumbSizeMultiplier, getThumbnailPriority(), coordinator);
           coordinator.setRequests(fullRequest, thumbnailRequest);
           return coordinator;
       } else {
           // Base case: no thumbnail.
           return obtainRequest(target, sizeMultiplier, priority, parentCoordinator);
       }
}

buildRequestRecursive方法前面一大部分主要是如果glide调用了override,就调用这个类的override方法,以及缩略图的处理,最终还是调用的obtainRequest方法

private Request obtainRequest(Target 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);
}

这个方法又调用了GenericRequest的obtain方法

public static  GenericRequest obtain(
       LoadProvider loadProvider,
       A model,
       Key signature,
       Context context,
       Priority priority,
       Target target,
       float sizeMultiplier,
       Drawable placeholderDrawable,
       int placeholderResourceId,
       Drawable errorDrawable,
       int errorResourceId,
       Drawable fallbackDrawable,
       int fallbackResourceId,
       RequestListener requestListener,
       RequestCoordinator requestCoordinator,
       Engine engine,
       Transformation transformation,
       Class transcodeClass,
       boolean isMemoryCacheable,
       GlideAnimationFactory animationFactory,
       int overrideWidth,
       int overrideHeight,
       DiskCacheStrategy diskCacheStrategy) {
   @SuppressWarnings("unchecked")
   GenericRequest request = (GenericRequest) REQUEST_POOL.poll();
   if (request == null) {
       request = new GenericRequest();
   }
   request.init(loadProvider,
           model,
           signature,
           context,
           priority,
           target,
           sizeMultiplier,
           placeholderDrawable,
           placeholderResourceId,
           errorDrawable,
           errorResourceId,
           fallbackDrawable,
           fallbackResourceId,
           requestListener,
           requestCoordinator,
           engine,
           transformation,
           transcodeClass,
           isMemoryCacheable,
           animationFactory,
           overrideWidth,
           overrideHeight,
           diskCacheStrategy);
   return request;
}

REQUEST_POOL.poll() 核心代码就这一句,调用了请求池的poll方法,获取request对象,如果请求池中这个对象为空,那么就创建一个GenericRequest对象,然后调用request对象的init方法进行初始化。

4.6 runRequest方法:这个方法就是执行图片请求的方法

public void runRequest(Request request) {
       requests.add(request);
       if (!isPaused) {
           request.begin();
       } else {
           pendingRequests.add(request);
       }
}

这个方法内部的逻辑是判断是不是加载状态,如果是加载状态,就调用request.begin()方法,否则就把这个请求加入到等待执行的请求队列中去。

4.7 begin方法: 真正执行request请求的方法

@Override
public void begin() {
    startTime = LogTime.getLogTime();
    if (model == null) {
        onException(null);
        return;
    }

    status = Status.WAITING_FOR_SIZE;
    if (Util.isValidDimensions(overrideWidth, overrideHeight))           {
        onSizeReady(overrideWidth, overrideHeight);
    } else {
        target.getSize(this);
    }

    if (!isComplete() && !isFailed() && canNotifyStatusChanged()) {
        target.onLoadStarted(getPlaceholderDrawable());
    }
    if (Log.isLoggable(TAG, Log.VERBOSE)) {
        logV("finished run method in " + LogTime.getElapsedMillis(startTime));
    }
}

这个方法的逻辑是如果glide调用了override方法,则调用onSizeReady方法,否则调用target.getSize(this);其实后面这个方法的内部也是会调用onSizeReady方法。
如果图片没有加载完成,并且图片不是加载失败状态,就给这个target设置默认占位图。

4.8 Target对象的getSize方法

@Override
public void getSize(SizeReadyCallback cb) {
    sizeDeterminer.getSize(cb);
}

public void getSize(SizeReadyCallback cb) {
    int currentWidth = getViewWidthOrParam();
    int currentHeight = getViewHeightOrParam();
    if (isSizeValid(currentWidth) && isSizeValid(currentHeight)) {
        cb.onSizeReady(currentWidth, currentHeight);
    } else {
        if (!cbs.contains(cb)) {
            cbs.add(cb);
        }
        if (layoutListener == null) {
            final ViewTreeObserver observer = view.getViewTreeObserver();
            layoutListener = new SizeDeterminerLayoutListener(this);
            observer.addOnPreDrawListener(layoutListener);
        }
    }
}

如果图片宽高没有测量完则会执行else部分图片的测量,否则也是调用onSizeReady方法

4.9 GenericRequest的onSizeReady方法


@Override
 public void onSizeReady(int width, int height) {
     if (Log.isLoggable(TAG, Log.VERBOSE)) {
         logV("Got onSizeReady in " + LogTime.getElapsedMillis(startTime));
     }
     if (status != Status.WAITING_FOR_SIZE) {
         return;
     }
     status = Status.RUNNING;

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

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

     if (dataFetcher == null) {
         onException(new Exception("Failed to load model: \'" + model + "\'"));
         return;
     }
     ResourceTranscoder transcoder = loadProvider.getTranscoder();
     if (Log.isLoggable(TAG, Log.VERBOSE)) {
         logV("finished setup for calling load in " + LogTime.getElapsedMillis(startTime));
     }
     loadedFromMemoryCache = true;
     loadStatus = engine.load(signature, width, height, dataFetcher, loadProvider, transformation, transcoder,
             priority, isMemoryCacheable, diskCacheStrategy, this);
     loadedFromMemoryCache = resource != null;
     if (Log.isLoggable(TAG, Log.VERBOSE)) {
         logV("finished onSizeReady in " + LogTime.getElapsedMillis(startTime));
     }
 }

几个重要的对象
获取原始数据的类
ModelLoader modelLoader = loadProvider.getModelLoader();
//
final DataFetcher dataFetcher = modelLoader.getResourceFetcher(model, width, height);
//图片资源转换类
ResourceTranscoder transcoder = loadProvider.getTranscoder();
//Engine类: 负责启动负载并管理活动和缓存的资源类
loadStatus = engine.load(signature, width, height, dataFetcher, loadProvider, transformation, transcoder,
         priority, isMemoryCacheable, diskCacheStrategy, this);

4.10 DrawableTypeRequest类的buildProvider方法得到LoadProvider对象


  private static  FixedLoadProvider buildProvider(Glide glide,
           ModelLoader streamModelLoader,
           ModelLoader fileDescriptorModelLoader, Class<Z> resourceClass,
           Class<R> transcodedClass,
           ResourceTranscoder<Z, R> transcoder) {
       if (streamModelLoader == null && fileDescriptorModelLoader == null) {
           return null;
       }

       if (transcoder == null) {
           transcoder = glide.buildTranscoder(resourceClass, transcodedClass);
       }
       DataLoadProvider dataLoadProvider = glide.buildDataProvider(ImageVideoWrapper.class,
               resourceClass);
       ImageVideoModelLoader modelLoader = new ImageVideoModelLoader(streamModelLoader,
               fileDescriptorModelLoader);
       return new FixedLoadProvider(modelLoader, transcoder, dataLoadProvider);
   }


 @Override
   public DataFetcher getResourceFetcher(A model, int width, int height) {
       DataFetcher streamFetcher = null;
       if (streamLoader != null) {
           streamFetcher = streamLoader.getResourceFetcher(model, width, height);
       }
       DataFetcher fileDescriptorFetcher = null;
       if (fileDescriptorLoader != null) {
           fileDescriptorFetcher = fileDescriptorLoader.getResourceFetcher(model, width, height);
       }

       if (streamFetcher != null || fileDescriptorFetcher != null) {
           return new ImageVideoFetcher(streamFetcher, fileDescriptorFetcher);
       } else {
           return null;
       }
   }


public interface LoadProvider<A, T, Z, R> extends DataLoadProvider<T, Z> {


    ModelLoader getModelLoader();

    ResourceTranscoder getTranscoder();
}


public interface DataLoadProvider<T, Z> {


    ResourceDecoder getCacheDecoder();


    ResourceDecoder getSourceDecoder();


    Encoder getSourceEncoder();


    ResourceEncoder getEncoder();
}

上面主要是创建LoadProvider对象,LoadProvider这个类主要负责图片的编码解码。

4.11 DataFetcher类


public interface DataFetcher {

    T loadData(Priority priority) throws Exception;


    void cleanup();


    String getId();


    void cancel();
}

这个类主要负责将流资源转换为glide实际加载图片需要的数据,比如byte[] ,file,uri,url等。

4.12 Engine类的load方法


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) {
    Util.assertMainThread();
    long startTime = LogTime.getLogTime();

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

    if (Log.isLoggable(TAG, Log.VERBOSE)) {
        logWithTimeAndKey("Started new load", startTime, key);
    }
    return new LoadStatus(cb, engineJob);
}

1) 通过buildKey方法构建图片缓存key对象,参数有10多个之多,比如id,签名,图片大小,数据的编码解码等等…

2)根据key从缓存中去获取缓存图片数据loadFromCache(key, isMemoryCacheable);

3)如果缓存不为空,则会调用 cb.onResourceReady(cached)方法,加载缓存数据

4)如果上面获取的缓存还是为空,则调用下面的方法继续去获取缓存数据loadFromActiveResources(key, isMemoryCacheable);

5)如果缓存不为空,也会调用cb.onResourceReady(active)方法去加载缓存数据。

6)否则会通过EngineJob这个Runnable类去加载图片。

4.13 EngineRunnable类

@Override
  public void run() {
      if (isCancelled) {
          return;
      }

      Exception exception = null;
      Resource resource = null;
      try {
          resource = decode();
      } catch (Exception e) {
          if (Log.isLoggable(TAG, Log.VERBOSE)) {
              Log.v(TAG, "Exception decoding", e);
          }
          exception = e;
      }

      if (isCancelled) {
          if (resource != null) {
              resource.recycle();
          }
          return;
      }

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

private void onLoadComplete(Resource resource) {
        manager.onResourceReady(resource);
}

@Override
  public void onResourceReady(final Resource resource) {
      this.resource = resource;
      MAIN_THREAD_HANDLER.obtainMessage(MSG_COMPLETE, this).sendToTarget();
  }

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


@Override
  public void onException(final Exception e) {
      this.exception = e;
      MAIN_THREAD_HANDLER.obtainMessage(MSG_EXCEPTION, this).sendToTarget();
  }

private void handleExceptionOnMainThread() {
      if (isCancelled) {
          return;
      } else if (cbs.isEmpty()) {
          throw new IllegalStateException("Received an exception without any callbacks to notify");
      }
      hasException = true;

      listener.onEngineJobComplete(key, null);

      for (ResourceCallback cb : cbs) {
          if (!isInIgnoredCallbacks(cb)) {
              cb.onException(exception);
          }
      }
}

run方法首先是去解码图片,然后判断有没有图片加载有没有取消,如果用户取消了加载,则回收资源,return,否则如果解码得到的Resource不为空则调用onLoadComplete加载完成的方法,加载完成通过Handler发送一个消息,更新UI,最终会调用EngineJob的handleResultOnMainThread方法,否则调用加载失败的方法,调用onException方法,也是通过Handler发送一个消息,更新UI,最终会调用handleExceptionOnMainThread方法

5. 图片的内存缓存

5.1 生成缓存key


public  LoadStatus load(Key signature, int width, int height, DataFetcher fetcher,
        DataLoadProvider loadProvider, Transformation transformation, ResourceTranscoder transcoder,
        Priority priority, boolean isMemoryCacheable, DiskCacheStrategy diskCacheStrategy, ResourceCallback cb) {
    Util.assertMainThread();
    long startTime = LogTime.getLogTime();

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

}

fetcher.getId()方法获得了一个id字符串,这个字符串也就是我们要加载的图片的唯一标识,比如说如果是一张网络上的图片的话,那么这个id就是这张图片的url地址。

EngineKeyl类主要重写了equal()和hashCode()方法。

Glide内存缓存的实现自然也是使用的LruCache算法。不过除了LruCache算法之外,Glide还结合了一种弱引用的机制,共同完成了内存缓存功能。

5.2 ModelLoader对象

我们当时分析到了在loadGeneric()方法中会调用Glide.buildStreamModelLoader()方法来获取一个ModelLoader对象


public static  ModelLoader buildStreamModelLoader(Class modelClass, Context context) {
    return buildModelLoader(modelClass, InputStream.class, context);
}

//构建ModelLoader对象
 public static  ModelLoader buildModelLoader(Class modelClass, Class resourceClass,
        Context context) {
     if (modelClass == null) {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "Unable to load null model, setting placeholder only");
        }
        return null;
    }
    return Glide.get(context).getLoaderFactory().buildModelLoader(modelClass, resourceClass);
}

//Glide的静态方法,用于返回Glide对象
public static Glide get(Context context) {
    if (glide == null) {
        synchronized (Glide.class) {
            if (glide == null) {
                Context applicationContext = context.getApplicationContext();
                List modules = new ManifestParser(applicationContext).parse();

                GlideBuilder builder = new GlideBuilder(applicationContext);
                for (GlideModule module : modules) {
                    module.applyOptions(applicationContext, builder);
                }
                glide = builder.createGlide();
                for (GlideModule module : modules) {
                    module.registerComponents(applicationContext, glide);
                }
            }
        }
    }

    return glide;
}

//创建并返回一个Glide对象
Glide createGlide() {
    if (sourceService == null) {
        final int cores = Math.max(1, Runtime.getRuntime().availableProcessors());
        sourceService = new FifoPriorityThreadPoolExecutor(cores);
    }
    if (diskCacheService == null) {
        diskCacheService = new FifoPriorityThreadPoolExecutor(1);
    }

    MemorySizeCalculator calculator = new MemorySizeCalculator(context);
    if (bitmapPool == null) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            int size = calculator.getBitmapPoolSize();
            bitmapPool = new LruBitmapPool(size);
        } else {
            bitmapPool = new BitmapPoolAdapter();
        }
    }

    if (memoryCache == null) {
        memoryCache = new LruResourceCache(calculator.getMemoryCacheSize());
    }

    if (diskCacheFactory == null) {
        diskCacheFactory = new InternalCacheDiskCacheFactory(context);
    }

    if (engine == null) {
        engine = new Engine(memoryCache, diskCacheFactory, diskCacheService, sourceService);
    }

    if (decodeFormat == null) {
        decodeFormat = DecodeFormat.DEFAULT;
    }

    return new Glide(engine, memoryCache, bitmapPool, context, decodeFormat);
}

你会发现这里new出了一个LruResourceCache,并把它赋值到了memoryCache这个对象上面。你没有猜错,这个就是Glide实现内存缓存所使用的LruCache对象了。

5.3 内存缓存读取

实现内存缓存的读取其实还是在Engine类的load方法,源码看下:

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) {
    Util.assertMainThread();
    long startTime = LogTime.getLogTime();

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

    if (Log.isLoggable(TAG, Log.VERBOSE)) {
        logWithTimeAndKey("Started new load", startTime, key);
    }
    return new LoadStatus(cb, engineJob);
}

1) 通过buildKey方法构建图片缓存key对象,参数有10多个之多,比如id,签名,图片大小,数据的编码解码等等…

2)根据key从缓存中去获取缓存图片数据 这个使用的是Lrucache实现的loadFromCache(key, isMemoryCacheable);

3)如果缓存不为空,则会调用cb.onResourceReady(cached)方法,加载缓存数据

4)如果上面获取的缓存还是为空,则调用下面的方法继续去获取正在加载的图片数loadFromActiveResources(key,isMemoryCacheable);这个是使用弱引用实现的。

5)如果缓存不为空,也还是调用cb.onResourceReady(active)方法去加载缓存数据。

6)否则会通过EngineJob这个Runnable类去加载图片。

5.3.1 loadFromCache和loadFromActiveResources方法


loadFromCache方法
private EngineResource loadFromCache(Key key, boolean isMemoryCacheable) {
    if (!isMemoryCacheable) {
        return null;
    }

    EngineResource cached = getEngineResourceFromCache(key);
    if (cached != null) {
        cached.acquire();
        activeResources.put(key, new ResourceWeakReference(key, cached, getReferenceQueue()));
    }
    return cached;
}


@SuppressWarnings("unchecked")
private EngineResource getEngineResourceFromCache(Key key) {
    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;
}

loadFromActiveResources方法
private EngineResource loadFromActiveResources(Key key, boolean isMemoryCacheable) {
    if (!isMemoryCacheable) {
        return null;
    }

    EngineResource active = null;
    WeakReference> activeRef = activeResources.get(key);
    if (activeRef != null) {
        active = activeRef.get();
        if (active != null) {
            active.acquire();
        } else {
            activeResources.remove(key);
        }
    }

    return active;
}

1) loadFromCache()方法是通过 getEngineResourceFromCache()方法来获取缓存。在这个方法中,会使用缓存Key来从cache当中取值,而这里的cache对象就是在构建Glide对象时创建的LruResourceCache,那么说明这里其实使用的就是LruCache算法了。

2)当我们从LruResourceCache中获取到缓存图片之后会将它从缓存中移除,然后将这个缓存图片存储到activeResources当中。activeResources就是一个弱引用的HashMap,用来缓存正在使用中的图片,我们可以看到,loadFromActiveResources()方法就是从activeResources这个HashMap当中取值的。使用activeResources来缓存正在使用中的图片,可以保护这些图片不会被LruCache算法回收掉,概括一下来说,就是如果能从内存缓存当中读取到要加载的图片,那么就直接进行回调,如果读取不到的话,才会开启线程执行后面的图片加载逻辑。

5.4 内存缓存的写入操作


@Override
public void onResourceReady(final Resource resource) {
    this.resource = resource;
    MAIN_THREAD_HANDLER.obtainMessage(MSG_COMPLETE, this).sendToTarget();
}

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;

    // Hold on to resource for duration of request so we don't recycle it in the middle of notifying if it
    // synchronously released by one of the callbacks.
    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();
}

static class EngineResourceFactory {
    public  EngineResource build(Resource resource, boolean isMemoryCacheable) {
        return new EngineResource(resource, isMemoryCacheable);
    }
}

这里通过EngineResourceFactory构建出了一个包含图片资源的EngineResource对象,然后通过 listener.onEngineJobComplete(key, engineResource);这个代码将这个对象回调到Engine的onEngineJobComplete()方法当中


 @SuppressWarnings("unchecked")
@Override
public void onEngineJobComplete(Key key, EngineResource resource) {
    Util.assertMainThread();
    if (resource != null) {
        resource.setResourceListener(key, this);

        if (resource.isCacheable()) {
            activeResources.put(key, new ResourceWeakReference(key, resource, getReferenceQueue()));
        }
    }
    jobs.remove(key);
}

回调过来的EngineResource被put到了activeResources当中,也就是在这里写入的缓存,不过这只是弱引用缓存,还有另外一种LruCache缓存是在哪里写入的呢?这就要介绍一下EngineResource中的一个引用机制了,观察刚才的handleResultOnMainThread()方法,分别有调用EngineResource的acquire()方法,和调用它的release()方法。其实,EngineResource是用一个acquired变量用来记录图片被引用的次数,调用acquire()方法会让变量加1,调用release()方法会让变量减1


void acquire() {
    if (isRecycled) {
        throw new IllegalStateException("Cannot acquire a recycled resource");
    }
    if (!Looper.getMainLooper().equals(Looper.myLooper())) {
        throw new IllegalThreadStateException("Must call acquire on the main thread");
    }
    ++acquired;
}

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

当acquired变量大于0的时候,说明图片正在使用中,也就应该放到activeResources弱引用缓存当中。而经过release()之后,如果acquired变量等于0了,说明图片已经不再被使用了,那么就会调用listener的onResourceReleased()方法来释放资源,这个listener就是Engine对象

@Override
public void onResourceReleased(Key cacheKey, EngineResource resource) {
    Util.assertMainThread();
    activeResources.remove(cacheKey);
    if (resource.isCacheable()) {
        cache.put(cacheKey, resource);
    } else {
        resourceRecycler.recycle(resource);
    }
}

这里首先会将缓存图片从activeResources中移除,然后再将它put到LruResourceCache当中。这样也就实现了正在使用中的图片使用弱引用来进行缓存,不在使用中的图片使用LruCache来进行缓存的功能。

6. 总结

  1. with方法总结

    width方法最终目的都是通过RequestManagerRetriever对象的get方法获取RequestManager对象,传入参数主要分Application类型和非Application类型。

    (1) 如果with方法传入的是Application,会通过调用getApplicationManager()来获取一个RequestManager对象,不需要处理生命周期,因为Application对象的生命周期就是应用程序的生命周期。

    (2) 如果with方法传入的不是Application类型,最终流程都是一样,那就是会向当前的Activity当中添加一个隐藏的Fragment,通过调用fragmentGet方法创建隐藏fragment,返回RequestManager对象,创建隐藏fragment的目的是Glide需要知道加载图片加载的生命周期,可是Glide并没有办法知道Activity的生命周期,于是Glide就使用了添加隐藏Fragment的这种小技巧,因为Fragment的生命周期和Activity是同步的,如果Activity被销毁了,Fragment是可以监听到的,这样Glide就可以捕获这个事件并停止图片加载了。

    (3) 如果我们是在非主线程当中使用的Glide,那么不管你是传入的Activity还是Fragment,都会被强制当成Application来处理,调用getApplicationManager()来获取RequestManager对象。

  2. load方法总结

    (1) 参数类型:String,File,byte[],URL,图片资源ID,Uri,我这里只看参数类型为String类型的,这些方法都会返回DrawableTypeRequest对象。

    (2) 两个重要方法是asBitmap方法和asGif方法,asBitmap方法会返回BitmapTypeRequest类型,这个方法会将图片强制转换为静态图片,asGif方法会返回GifTypeRequest类型,将图片强制转换为动态图片,如果图片是静态图片,则会加载失败。

    (3) DrawableRequestBuilder类:DrawableTypeRequest的直接父类,这里面提供了glide加载图片过程的很多方法,比如animate,centerCrop,crossFade,error,fitCenter,placeholder,skipMemoryCache,priority等等…

    (4) GenericRequestBuilder类: DrawableRequestBuilder的父类,这里面提供了绝大部分glide加载图片过程中的方法,它的子类都是直接或间接实现了这个父类。

  3. into方法总结

    (1)into方法最终会调用into(Target target)方法返回一个target对象,通过glide.buildImageViewTarget(view, transcodeClass)创建一个target对象。

    (2) 创建target对象主要分两种,如果你在使用Glide加载图片的时候调用了asBitmap()方法,那么这里就会构建出BitmapImageViewTarget对象,返回BitmapImageViewTarget对象,否则返回GlideDrawableImageViewTarget对象。

    (3) into(Target target)方法,这个方法会通过target对象获取request对象,然后清除之前的request对象,回收request对象,然后重新构建一个新的request对象,并且给这个target设置request对象,这其实就是好比listView加载图片时候给图片设置tag,防止图片错位问题,这里其实就是给target设置tag为request,也是为了防止图片错位,这里requestTracker.runRequest这个方法是执行这个请求。

    (4) buildRequest方法:构建一个request对象,然后调用target.setRequest给target设置tag,防止图片错乱。

    (5) runRequest方法:这个方法是执行图片请求的方法,这个方法内部的逻辑是判断图片当前是不是加载状态,如果是加载状态,就调用request.begin()方法,否则就把这个请求加入到等待执行的请求队列中去等待加载。

    (6) begin方法: 这个方法的逻辑是如果glide调用了override方法,指定了图片宽高,则调用onSizeReady方法,否则调用target.getSize(this)去测量图片宽高,但是最终也会通过回调形式调用onSizeReady方法。

    (7) onSizeReady方法: 这个方法里面有一些重要的对象,这个主要是调用engine.load方法去执行这个图片请求。

    (8) Engine类的load方法:

    1) 通过buildKey方法构建图片缓存key对象,参数有10多个之多,比如id,签名,图片大小,数据的编码解码等等...
    2)根据key从缓存中去获取缓存图片数据
    EngineResource cached = loadFromCache(key, isMemoryCacheable);
    3)如果缓存不为空,则会调用 cb.onResourceReady(cached)方法,加载缓存数据
    4)如果上面获取的缓存还是为空,则调用下面的方法继续去获取正在加载的图片数据
    EngineResource active = loadFromActiveResources(key, isMemoryCacheable);
    5)如果缓存不为空,也会调用cb.onResourceReady(active)方法去加载缓存数据。
    6)否则会通过EngineJob这个Runnable类去加载图片。
    

    (9) EngineRunnable类的run方法:run方法首先是去解码图片,然后判断有没有图片加载有没有取消,如果用户取消了加载,则回收资源,return,否则如果解码得到的Resource不为空则调用onLoadComplete加载完成的方法,加载完成通过Handler发送一个消息,更新UI,最终会调用EngineJob的handleResultOnMainThread方法,否则调用加载失败的方法,调用onException方法,也是通过Handler发送一个消息,更新UI,最终会调用handleExceptionOnMainThread方法。

    (10) 几个重要的类

    RequestManager:监听组件生命周期,管理各种图片加载,
    RequestTracker:跟踪图片请求,执行请求,删除请求,添加请求等等...
    ModeLoader:数据来源加载成原始数据
    LifecycleListener:glide绑定生命周期的回调接口
    DataLoadProvider:数据编解码
    LoadProvider:继承了DataLoadProvider
    DataFetcher:原始数据转换为我们可以用的不同数据类型,比如url,字节数组,文件等等...
    ResourceTranscoder:原始数据解码
    Engine:开启图片加载的类,两个重要方法 equals和hashCode方法
    EngineRunnable: 执行图片加载请求的子线程类
    

    (11) 图片的内存缓存是通过LruCache和弱引用的方式来实现的,正在使用中的图片使用弱引用来进行缓存,不再使用中的图片使用LruCache来进行缓存的功能,这就是Glide内存缓存的实现原理。

7. 联系方式:

QQ: 1509815887

你可能感兴趣的:(开发类,源码阅读)