Glide源码流程分析

几个核心类简介:


DataFetcher   从不同的地方拉去数据,是一个接口,
 实现类,负责拉取


EngineRunnable    负责组合各功能对象,组织加载  类


ResourceDecoder 负责资源解码接口,StreamBitmapDecoder 子类,负责解析流

ResourceEncoder 负责资源编码


DataLoadProvider 接口,里面可以获取必要的编码和节码类ResourceDecoder ,ResourceEncoder 


BitmapDecoder    接口,负责从一个资源解析成Bitmap    实现类Downsampler,从流解析成Bitmap
Downsampler 是抽象类,里面又很多,静态内部成员变量,负责具体的,解析

BitmapResource 对Bitmap的包装,可以获取Bitmap,并且返回大小,可以释放bitmap

ResourceCallback 资源加载回调

Engine   中的load 方法是开始,
load方法,再GenericRequest  中的onSizeReady中调用

GenericRequest  会注册ResourceCallback ,SizeReadyCallback,回调,并且负责RequestListener回调和Target回调

SizeReadyCallback,再大小固定轴回调

ViewTarget   中有一个对象SizeDeterminer

SizeDeterminer 负责确定View的大小    SizeDeterminer 接受一个View参数,然后再内部注册
 ViewTreeObserver observer = view.getViewTreeObserver();
            if (observer.isAlive()) {
                observer.removeOnPreDrawListener(layoutListener);
            }
监听绘制完成的回调,SizeDeterminer 中会收集SizeReadyCallback监听的集合,然后再绘制完成的监听中,通知SizeReadyCallback,的方法,然后久通知到了Engine   的init

Target的getSize()会调用SizeDeterminer 的getSize()
SizeDeterminer 的getSize()中会先判断View和宽度和高度是否有效,如果无效,也会注册监听


Target.....beigin.......getSize().....然后再SizeReadyCallback的。-------onSizeReady(int width, int height);-----------Engine.load()


DrawableTypeRequest  继承自DrawableRequestBuilder  负责很多默认对象的填充,例如ModelLoader ,

EngineJob   负责执行EngineRunnable    并且也负责ResourceCallback    回调
内部有缓存线程池,执行EngineRunnable    的线程池,并且注册了监听到EngineRunnable    ,
EngineRunnable    把执行结果,通过回调EngineRunnable.EngineRunnableManager 
给EngineJob   ,EngineJob   再回调给ResourceCallback    ,并且管理失败的EngineRunnable

EngineResource 包装了resource ,还包装了一个回调


ModelLoader 负责,根据宽高和model,找到对应数据加载DataFetcher

 Glide.with(mContext).pauseRequests();
    Glide.with(mContext)
        //.using(null) //这个方法是设置自己的资源拉取器 ModelLoader<A, T> modelLoader, Class<T> dataClass
        //可以只定义资源拉取,也可以定义LoadProvider中的所有内容,定义,从资源下载,解码,转换,图片变换的所有过程
        .fromString()
        .load(path)
        .animate(0)//设置动画
        .transform(new CenterCrop(mContext))//设置图片变换可以设置多个
        .skipMemoryCache(false)//可以跳过
        .diskCacheStrategy(DiskCacheStrategy.ALL)
        .centerCrop()  //按比例缩放填充控件,再内部会转化为transform,所以如果也需要其他转换,请自己实现这个,然后一起设置
        .error(0)//加载错误图片显示
        .placeholder(0)//加载中占位符
        .fallback(0)//如果数据model设置的null,就会显示这个图片,否则会报错
        .listener(new RequestListener<String, GlideDrawable>() {
          @Override
          public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
            return false;
          }

          @Override
          public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
            return false;
          }
        })


        //下面能再这里设置,然后替换掉,原来创建的原因,主要再ChildLoadProvider类
        //.sourceEncoder()  //替换从Factory 中创建的源文件,编码器,编码成流
       // .cacheDecoder()//从缓存文件中,解码成图片资源  从File 解码成GifBitmapWrapper  替换Factory中创建的
        //.decoder()  //可以再这里设置资源解码器,替换按照类型,从Factory中创建的  从ImageVideoWrapper
    // (inputStream 和ParcelFileDescriptor)的包装类,解码成GifBitmapWrapper
       // .encoder() //可以再这里设置,替换上面按照类型,从Factory中取的   把资源编码成输出流

        .priority(Priority.NORMAL)
        .into(mImageView);

  Glide.with(mContext);
    
   Glide. public static RequestManager with(Context context) {
        RequestManagerRetriever retriever = RequestManagerRetriever.get();//从RequestManagerRetriever(RequestManager的管理者,负责activity,Fragment,和RequestManager的对应)
        return retriever.get(context);//从RequestManagerRetriever 中找到和上下文,对应的RequestManager
    }
RequestManger,主要负责构建RequstBuilder ,负责感受上下文生命周期的回调,然后通过RequestTracker 管理Request的生命周期

-》      RequestManger.fromString()      //生成DrawableTypeRequest 是GenericRequestBuilder的非直接子类,主要负责,数据model 类型,数据类型,资源类型 ,转化后类型
                //再确定使用那种类型的,ModelLoader,ResourceDecoder,ResourceTranscoder,并且通过我们传递的参数,构建Request
-》      .animate(0)//设置动画
        .transform(new CenterCrop(mContext))//设置图片变换可以设置多个
        .skipMemoryCache(false)//可以跳过
        .diskCacheStrategy(DiskCacheStrategy.ALL)
        .centerCrop()  //按比例缩放填充控件,再内部会转化为transform,所以如果也需要其他转换,请自己实现这个,然后一起设置
        .error(0)//加载错误图片显示
        .placeholder(0)//加载中占位符
        .fallback(0)//如果数据model设置的null,就会显示这个图片,否则会报错
        .listener(new RequestListener<String, GlideDrawable>() {
          @Override
          public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
            return false;
          }

          @Override
          public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
            return false;
          }
        })


        //下面能再这里设置,然后替换掉,原来创建的原因,主要再ChildLoadProvider类
        //.sourceEncoder()  //替换从Factory 中创建的源文件,编码器,编码成流
       // .cacheDecoder()//从缓存文件中,解码成图片资源  从File 解码成GifBitmapWrapper  替换Factory中创建的
        //.decoder()  //可以再这里设置资源解码器,替换按照类型,从Factory中创建的  从ImageVideoWrapper
    // (inputStream 和ParcelFileDescriptor)的包装类,解码成GifBitmapWrapper
       // .encoder() //可以再这里设置,替换上面按照类型,从Factory中取的   把资源编码成输出流

        .priority(Priority.NORMAL)//设置请求的优先级,会影响请求的排序

上面的设置,都设置到GenericRequestBuilder或者它的子类中,用来构建Request
-》   .into(mImageView);  
  @Override
   DrawableRequestBuilder. public Target<GlideDrawable> into(ImageView view) {
        return super.into(view);
    }
-》 super.into(view);
 GenericRequestBuilder.public Target<TranscodeType> into(ImageView view) {
        Util.assertMainThread();
        if (view == null) {
            throw new IllegalArgumentException("You must pass in a non null View");
        }

        if (!isTransformationSet && view.getScaleType() != null) {//如果没有自己设置Transformation,就会根据View的ScaleType设置对应的Transformation
            switch (view.getScaleType()) {
                case CENTER_CROP:
                    applyCenterCrop();  //Transformation
                    break;
                case FIT_CENTER:
                case FIT_START:
                case FIT_END:
                    applyFitCenter();//Transformation
                    break;
                //$CASES-OMITTED$
                default:
                    // Do nothing.
            }
        }

        return into(glide.buildImageViewTarget(view, transcodeClass));
    }
-》glide.buildImageViewTarget(view, transcodeClass)  根据View和转换后数据的类型,获取对应Target  获取到GlideDrawableImageViewTarget
-》 into(glide.buildImageViewTarget(view, transcodeClass));
GenericRequestBuilder. public <Y extends Target<TranscodeType>> 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();//获取Target之前的Request

        if (previous != null) {
            previous.clear();                                       //清空资源
            requestTracker.removeRequest(previous);//从移除request
            previous.recycle();                                  //把请循环
        }

        Request request = buildRequest(target);//构建请求                  
        target.setRequest(request);                    //请求设置到target
        lifecycle.addListener(target);                 //为Target添加感应上下文的生命周期
        requestTracker.runRequest(request);     //开始运行Request

        return target;
    }
-》Request request = buildRequest(target);
   GenericRequestBuilder.  private Request buildRequest(Target<TranscodeType> target) {
        if (priority == null) {
            priority = Priority.NORMAL;
        }
        return buildRequestRecursive(target, null);
    }
-》GenericRequestBuilder. buildRequestRecursive(target, null);
 GenericRequestBuilder. private Request buildRequestRecursive(Target<TranscodeType> 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);//创建一个Request
        }
    }
-》    GenericRequestBuilder. obtainRequest(target, sizeMultiplier, priority, parentCoordinator);//创建一个Request
 GenericRequestBuilder. 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);
    }    
-》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);
public static <A, T, Z, R> GenericRequest<A, T, Z, R> obtain(
            LoadProvider<A, T, Z, R> loadProvider,
            A model,
            Key signature,
            Context context,
            Priority priority,
            Target<R> target,
            float sizeMultiplier,
            Drawable placeholderDrawable,
            int placeholderResourceId,
            Drawable errorDrawable,
            int errorResourceId,
            Drawable fallbackDrawable,
            int fallbackResourceId,
            RequestListener<? super A, R> requestListener,
            RequestCoordinator requestCoordinator,
            Engine engine,
            Transformation<Z> transformation,
            Class<R> transcodeClass,
            boolean isMemoryCacheable,
            GlideAnimationFactory<R> animationFactory,
            int overrideWidth,
            int overrideHeight,
            DiskCacheStrategy diskCacheStrategy) {
        @SuppressWarnings("unchecked")
        GenericRequest<A, T, Z, R> request = (GenericRequest<A, T, Z, R>) REQUEST_POOL.poll();  //从请求池中获取一个请求
        if (request == null) {
            request = new GenericRequest<A, T, Z, R>();
        }
//为请求设置请求参数
        request.init(loadProvider,//提供下载,编码,解码,转换,变换功能
                model,//数据model
                signature,  //签名
                context,//上下文
                priority,//加载优先级
                target,//target相应监听
                sizeMultiplier,//支持对资源进行缩放
                placeholderDrawable,//加载中占位符
                placeholderResourceId,
                errorDrawable,//失败占位符
                errorResourceId,
                fallbackDrawable,//model为null的占位符
                fallbackResourceId,
                requestListener,//请求的监听
                requestCoordinator,
                engine,//主要负责执行请求
                transformation,//图片变换操作
                transcodeClass,//需要转换成的数据类型
                isMemoryCacheable,//是否支持使用内存缓存
                animationFactory,//动画集合,我们要使用动画,可以自己设置
                overrideWidth,//需要的最终的图片宽度
                overrideHeight,//需要的最终的图片高度
                diskCacheStrategy);//磁盘缓存的策略
        return request;
    }

-》我们再返回到        requestTracker.runRequest(request);     //开始运行Request  之前的设置,都比较简单
    public void runRequest(Request request) {
        requests.add(request);
        if (!isPaused) {
            request.begin();//开始执行request
        } else {
            pendingRequests.add(request);//并把reuqest,加入到记录中
        }
    }
-》GenericRequest.     request.begin();
   public void begin() {
        startTime = LogTime.getLogTime();
        if (model == null) {
            onException(null);//如果model是null,会直接走失败,然后把FallbackDrawable设置上去
            return;
        }

        status = Status.WAITING_FOR_SIZE;
        if (Util.isValidDimensions(overrideWidth, overrideHeight)) {//如果设置了固定的有效的宽高,直接执行
            onSizeReady(overrideWidth, overrideHeight);
        } else {
            target.getSize(this);//如果没有指定宽度,从target获取高度,并且传递GenericRequest               按照这个走
        }

        if (!isComplete() && !isFailed() && canNotifyStatusChanged()) {
            target.onLoadStarted(getPlaceholderDrawable());//执行target中开始回调
        }
        if (Log.isLoggable(TAG, Log.VERBOSE)) {
            logV("finished run method in " + LogTime.getElapsedMillis(startTime));
        }
    }
-》target.getSize(SizeReadyCallback callback);   GenericRequest实现了这个回调,再View的宽高确定的时候,回调
接下来,我们分析Target,选择VewTarget分析,因为它的内部,实现监听绘制View之前的一个监听,来获取宽度和高度
public abstract class ViewTarget<T extends View, Z> extends BaseTarget<Z> {
    private static final String TAG = "ViewTarget";
    private static boolean isTagUsedAtLeastOnce = false;
    private static Integer tagId = null;

    protected final T view;
    private final SizeDeterminer sizeDeterminer;                                                 //可以得到,View的宽高

    @Override
    public void getSize(SizeReadyCallback cb) {                                //调用这个方法  其实调用的是 sizeDeterminer.getSize(cb);
        sizeDeterminer.getSize(cb);
    }

    /**
     * Stores the request using {@link View#setTag(Object)}.
     *
     * @param request {@inheritDoc}
     */
    @Override
    public void setRequest(Request request) {
        setTag(request);
    }
    @Override
    public Request getRequest() {
        Object tag = getTag();
        Request request = null;
        if (tag != null) {
            if (tag instanceof Request) {
                request = (Request) tag;
            } else {
                throw new IllegalArgumentException("You must not call setTag() on a view Glide is targeting");
            }
        }
        return request;
    }

    private void setTag(Object tag) {
        if (tagId == null) {
            isTagUsedAtLeastOnce = true;
            view.setTag(tag);
        } else {
            view.setTag(tagId, tag);
        }
    }

    private Object getTag() {
        if (tagId == null) {
            return view.getTag();
        } else {
            return view.getTag(tagId);
        }
    }

    @Override
    public String toString() {
        return "Target for: " + view;
    }

}
-》 sizeDeterminer.getSize(cb);

    private static class SizeDeterminer {
        // Some negative sizes (WRAP_CONTENT) are valid, 0 is never valid.
        private static final int PENDING_SIZE = 0;

        private final View view;
        private final List<SizeReadyCallback> cbs = new ArrayList<SizeReadyCallback>();

        private SizeDeterminerLayoutListener layoutListener;
        private Point displayDimens;

        public SizeDeterminer(View view) {
            this.view = view;
        }

        private void notifyCbs(int width, int height) {
            for (SizeReadyCallback cb : cbs) {
                cb.onSizeReady(width, height);
            }
            cbs.clear();
        }

        private void checkCurrentDimens() {//再监听中执行这个
            if (cbs.isEmpty()) {
                return;
            }

            int currentWidth = getViewWidthOrParam();//计算宽度
            int currentHeight = getViewHeightOrParam();//计算高度
            if (!isSizeValid(currentWidth) || !isSizeValid(currentHeight)) {
                return;
            }

            notifyCbs(currentWidth, currentHeight);//通知回调
            // Keep a reference to the layout listener and remove it here
            // rather than having the observer remove itself because the observer
            // we add the listener to will be almost immediately merged into
            // another observer and will therefore never be alive. If we instead
            // keep a reference to the listener and remove it here, we get the
            // current view tree observer and should succeed.
            ViewTreeObserver observer = view.getViewTreeObserver();
            if (observer.isAlive()) {
                observer.removeOnPreDrawListener(layoutListener);
            }
            layoutListener = null;
        }

        public void getSize(SizeReadyCallback cb) {                                                                     //执行这个方法
            int currentWidth = getViewWidthOrParam();
            int currentHeight = getViewHeightOrParam();
            if (isSizeValid(currentWidth) && isSizeValid(currentHeight)) {  //如果是有效的宽高,
                cb.onSizeReady(currentWidth, currentHeight);                    //直接调用回调                              
            } else {//如果没有宽高,
                // We want to notify callbacks in the order they were added and we only expect one or two callbacks to
                // be added a time, so a List is a reasonable choice.
                if (!cbs.contains(cb)) {
                    cbs.add(cb);
                }
                if (layoutListener == null) {
                    final ViewTreeObserver observer = view.getViewTreeObserver();
                    layoutListener = new SizeDeterminerLayoutListener(this);//设置监听
                    observer.addOnPreDrawListener(layoutListener);//监听View 绘制之前,然后调用    private void checkCurrentDimens()
                }
            }
        }

        private int getViewHeightOrParam() {
            final LayoutParams layoutParams = view.getLayoutParams();
            if (isSizeValid(view.getHeight())) {
                return view.getHeight();
            } else if (layoutParams != null) {
                return getSizeForParam(layoutParams.height, true /*isHeight*/);
            } else {
                return PENDING_SIZE;
            }
        }

        private int getViewWidthOrParam() {
            final LayoutParams layoutParams = view.getLayoutParams();
            if (isSizeValid(view.getWidth())) {
                return view.getWidth();
            } else if (layoutParams != null) {
                return getSizeForParam(layoutParams.width, false /*isHeight*/);
            } else {
                return PENDING_SIZE;
            }
        }

        private int getSizeForParam(int param, boolean isHeight) {
            if (param == LayoutParams.WRAP_CONTENT) {
                Point displayDimens = getDisplayDimens();
                return isHeight ? displayDimens.y : displayDimens.x;
            } else {
                return param;
            }
        }

        @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
        @SuppressWarnings("deprecation")
        private Point getDisplayDimens() {
            if (displayDimens != null) {
                return displayDimens;
            }
            WindowManager windowManager = (WindowManager) view.getContext().getSystemService(Context.WINDOW_SERVICE);
            Display display = windowManager.getDefaultDisplay();
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
                displayDimens = new Point();
                display.getSize(displayDimens);
            } else {
                displayDimens = new Point(display.getWidth(), display.getHeight());
            }
            return displayDimens;
        }

        private boolean isSizeValid(int size) {
            return size > 0 || size == LayoutParams.WRAP_CONTENT;
        }

        private static class SizeDeterminerLayoutListener implements ViewTreeObserver.OnPreDrawListener {//实现View树的回调,监听开始绘制
            private final WeakReference<SizeDeterminer> sizeDeterminerRef;

            public SizeDeterminerLayoutListener(SizeDeterminer sizeDeterminer) {
                sizeDeterminerRef = new WeakReference<SizeDeterminer>(sizeDeterminer);
            }

            @Override
            public boolean onPreDraw() {
                if (Log.isLoggable(TAG, Log.VERBOSE)) {
                    Log.v(TAG, "OnGlobalLayoutListener called listener=" + this);
                }
                SizeDeterminer sizeDeterminer = sizeDeterminerRef.get();
                if (sizeDeterminer != null) {
                    sizeDeterminer.checkCurrentDimens();                   //再开始绘制的时候,执行    sizeDeterminer.checkCurrentDimens();    
                }
                return true;
            }
        }
    }

-》执行GenericRequest.onSizeReady(width, height);

   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<A, T> modelLoader = loadProvider.getModelLoader();//获取数据拉取器创建工厂
        final DataFetcher<T> dataFetcher = modelLoader.getResourceFetcher(model, width, height);//创建数据拉取器

        if (dataFetcher == null) {
            onException(new Exception("Failed to load model: \'" + model + "\'"));
            return;
        }
        ResourceTranscoder<Z, R> 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);//开始由引擎执行操作,返回loadStatus ,可以取消请求
        loadedFromMemoryCache = resource != null;
        if (Log.isLoggable(TAG, Log.VERBOSE)) {
            logV("finished onSizeReady in " + LogTime.getElapsedMillis(startTime));
        }
    }
-》engine.load(signature, width, height, dataFetcher, loadProvider, transformation, transcoder,
                priority, isMemoryCacheable, diskCacheStrategy, this);//先只分析流程,具体单个细节流程,后面再分析单个方法
 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());                           //根据信息创建一个key,用于内存缓存,和磁盘缓存

        EngineResource<?> cached = loadFromCache(key, isMemoryCacheable);//如果允许内存缓存,会从内存缓存中获取,根据key
        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);//如可以允许内存缓存,从active(当前正在使用的资源),中获取图片
        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);//获取一个EngineJob ,每一个执行的工作,都会加入到这个map,能获取到对应的,说明正在执行
        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);//从engineJobFactory创建一个EngineJob ,负载再内部执行EngineRunnable,然后回调EngineJobListener(Engine实现)
        DecodeJob<T, Z, R> decodeJob = new DecodeJob<T, Z, R>(key, width, height, fetcher, loadProvider, transformation,
                transcoder, diskCacheProvider, diskCacheStrategy, priority);//创建解码job,负责拉取数据,解码数据,变换数据,转换数据
        EngineRunnable runnable = new EngineRunnable(engineJob, decodeJob, priority);//具体的执行操作,然后回调EngineRunnable.EngineRunnableManager(EngineJob 实现了这个接口 )
        jobs.put(key, engineJob);//把job保存起来
        engineJob.addCallback(cb);//把callback,加入到job中,这个cb是回调GenericRequest
        engineJob.start(runnable);//开始执行

        if (Log.isLoggable(TAG, Log.VERBOSE)) {
            logWithTimeAndKey("Started new load", startTime, key);
        }
        return new LoadStatus(cb, engineJob);
    }
-》     engineJob.start(runnable);//开始执行
    public void start(EngineRunnable engineRunnable) {
        this.engineRunnable = engineRunnable;
        future = diskCacheService.submit(engineRunnable);//Future,用来控制请求,放到子线程去执行engineRunnable.run
    }
-》engineRunnable.run
    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);//执行失败,回调到engineJob.submitForSource 或者.onException(e)
        } else {
            onLoadComplete(resource);//执行成功,engineJob.onResourceReady(resource)
        }
    }
-》分析 resource = engineRunnable.decode();//核心过程
private Resource<?> decode() throws Exception {
        if (isDecodingFromCache()) {
            return decodeFromCache();//从磁盘缓存中获取 ,先分析从磁盘中获取
        } else {
            return decodeFromSource();//从数据员拉取
        }
    }
-》engineRunnable.decodeFromCache();
   private Resource<?> decodeFromCache() throws Exception {
        Resource<?> result = null;
        try {
            result = decodeJob.decodeResultFromCache();//从结果缓存中获取,执行的类是decodeJob
        } catch (Exception e) {
            if (Log.isLoggable(TAG, Log.DEBUG)) {
                Log.d(TAG, "Exception decoding result from cache: " + e);
            }
        }

        if (result == null) {
            result = decodeJob.decodeSourceFromCache();//从源文件缓存中获取 ,执行的类是decodeJob
        }
        return result;
    }
-》 decodeJob.decodeResultFromCache();
  public Resource<Z> decodeResultFromCache() throws Exception {
        if (!diskCacheStrategy.cacheResult()) {//是否支持结果缓存
            return null;
        }

        long startTime = LogTime.getLogTime();
        Resource<T> transformed = loadFromCache(resultKey);//从缓存中获取
        if (Log.isLoggable(TAG, Log.VERBOSE)) {
            logWithTimeAndKey("Decoded transformed from cache", startTime);
        }
        startTime = LogTime.getLogTime();
        Resource<Z> result = transcode(transformed);//然后执行数据转换
        if (Log.isLoggable(TAG, Log.VERBOSE)) {
            logWithTimeAndKey("Transcoded transformed from cache", startTime);
        }
        return result;
    }
-》 decodeJob.loadFromCache(resultKey);//从缓存中获取  一会还会用到,不在重复分析
 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;//返回
    }
-》        Resource<Z> result =decodeJob. transcode(transformed);//然后执行数据转换
    private Resource<Z> transcode(Resource<T> transformed) {
        if (transformed == null) {
            return null;
        }
        return transcoder.transcode(transformed);//从一种数据转化为林一种
    }
-》再分析另一条,从源文件换种中获取 decodeJob.decodeSourceFromCache();,执行的方法类似,只是,再去除源文件之后,要执行       Resource<T> transformed = transform(decoded);数据变换
-》现在分析,从数据获取EngineRunnable.decodeFromSource();
  private Resource<?> decodeFromSource() throws Exception {
        return decodeJob.decodeFromSource();
    }
->decodeJob.decodeFromSource();
   public Resource<Z> decodeFromSource() throws Exception {
        Resource<T> decoded = decodeSource();//从数据源加载数据
        return transformEncodeAndTranscode(decoded);//变换数据,转化数据
    }
-》decodeJob.decodeSource();//从数据源加载数据
 private Resource<T> decodeSource() throws Exception {
        Resource<T> decoded = null;
        try {
            long startTime = LogTime.getLogTime();
            final A data = fetcher.loadData(priority);//从fetcher加载数据
            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                logWithTimeAndKey("Fetched data", startTime);
            }
            if (isCancelled) {
                return null;
            }
            decoded = decodeFromSourceData(data);//然后解码
        } finally {
            fetcher.cleanup();
        }
        return decoded;
    }
 -》decodeJob.decodeFromSourceData(data);
    private Resource<T> decodeFromSourceData(A data) throws IOException {
        final Resource<T> decoded;
        if (diskCacheStrategy.cacheSource()) {
            decoded = cacheAndDecodeSourceData(data);//缓存到文件,并且解码数据
        } else {
            long startTime = LogTime.getLogTime();
            decoded = loadProvider.getSourceDecoder().decode(data, width, height);//直接解码数据
            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                logWithTimeAndKey("Decoded from source", startTime);
            }
        }
        return decoded;
    }

-》再返回到,转换   transformEncodeAndTranscode(decoded);//变换数据,转化数据
  private Resource<Z> transformEncodeAndTranscode(Resource<T> decoded) {
        long startTime = LogTime.getLogTime();
        Resource<T> transformed = transform(decoded);//执行图片变换
        if (Log.isLoggable(TAG, Log.VERBOSE)) {
            logWithTimeAndKey("Transformed resource from source", startTime);
        }

        writeTransformedToCache(transformed);

        startTime = LogTime.getLogTime();
        Resource<Z> result = transcode(transformed);//执行图片转换,已分析,不在分析
        if (Log.isLoggable(TAG, Log.VERBOSE)) {
            logWithTimeAndKey("Transcoded transformed from source", startTime);
        }
        return result;
    }
-》Resource<T> transformed = transform(decoded);

transform(Resource<T> decoded) {
        if (decoded == null) {
            return null;
        }

        Resource<T> transformed = transformation.transform(decoded, width, height);
        if (!decoded.equals(transformed)) {
            decoded.recycle();
        }
        return transformed;
    }

//具体的缓存获取,和回调,需要用时序图分析


问题、
1.Glide中的RequestManager中的请求会不会积压很多,再页面关闭的收再释放? 

答:不会,Glide   的所有的请求都在RequestTracker 中,再当前活动,生命周期,关闭的时候,会清空所有的请求缓存,同时对于有View重用的地方,比如ListView,和RecycView
会再当前View被重用的时候,把上一次再本View上的请求,从RequestTracker 中移除,实现方式是通过把请求设置为当前View的tag,通过ViewTarget获取Tag,所以对于
再RecycView中进行大批量的请求,不会导致请求过多不能回收

Glide再RecycView中使用的时候,因为有条目重用的存在,Glide是如何保证图片不出现错乱的?

答:通过为View,设置一个Tag,Tag就是当前的Request,然后再这个View重用的时候,会获取这个View的Tag,如果存在,就是取消前一个请求,并且循环他,处理非常好,值得借鉴
避免了无用的请求。


感觉Glide框架中,那些模块思路设计很好
     1.类的功能单一,单一职责原则,让我大开眼界,感觉各个功能拆分的非常好,然后结合工厂设计模式,以类型为区分这些实现,
     2.监听View的绘制之前的监听,然后再开始数据的加载,保证了再变换数据,设置数据的时候,View的宽高是有效的
     3.RequestManager的设计,再每个活动中,添加Fragment,然后使用这个Fragment感知活动的生命周期,然后,做停止请求,刷新请求,然后可以集中管理这些请求(感知生命
       周期,不需要使用者去担心内存泄漏,去取消请求)
      4.文件缓存,内存缓存,activiyBitmap(活动的Bitmap)具体意义再哪里还不太清楚,猜测是,这个缓存是缓存正在使用的view,是弱引用,可以更好感知内存,回收资源
     5.BitmapPool的设计,很厉害,对于占用内存大小相同的Bitmap,可以重复使用他们,避免频繁的分配整块的内存(会引起频繁的gc,因为Bitmap需要的连续内存空间比较大),提高
      流畅度。
     6.扩展性非常好,因为功能拆分的很细,然后都是使用工厂模式创建,我们都可以注册使用的工厂,然后实现,可以覆盖,下载,解码,转换,变换,动画,等等功能


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值