美文网首页
Glide 源码分析(Version_3.7.0)

Glide 源码分析(Version_3.7.0)

作者: 大盗海洲 | 来源:发表于2019-05-24 19:41 被阅读0次

    使用方式

       Glide.with(this).load("url").into(imageView);
    

    with(activity)

          // Glide.java
        /**
         * Begin a load with Glide by passing in a context.
         *
         * <p>
         *     This method is appropriate for resources that will be used outside of the normal fragment or activity
         *     lifecycle (For example in services, or for notification thumbnails).
         * </p>
         *
         * @see #with(android.app.Activity)
         * @see #with(android.app.Fragment)
         * @see #with(android.support.v4.app.Fragment)
         * @see #with(android.support.v4.app.FragmentActivity)
          *可以是以上参数
         * @param context Any context, will not be retained.
         * @return A RequestManager for the top level application that can be used to start a load.
         */
        public static RequestManager with(Context context) {
            RequestManagerRetriever retriever = RequestManagerRetriever.get();
            return retriever.get(context);
        }
    
    

    使用饿汉式单例模式创建 RequestManagerRetriever

    /**
     * A collection of static methods for creating new {@link com.bumptech.glide.RequestManager}s or retrieving existing
     * ones from activities and fragment.
     */
    public class RequestManagerRetriever implements Handler.Callback {
      /**
         * Retrieves and returns the RequestManagerRetriever singleton.
         */
        public static RequestManagerRetriever get() {
            return INSTANCE;
        }
    
    
        /** The singleton instance of RequestManagerRetriever. */
        private static final RequestManagerRetriever INSTANCE = new RequestManagerRetriever();
    
    }
    
    
    //RequestManagerRetriever.java
    public class RequestManagerRetriever implements Handler.Callback {
       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)) {
                //是UI线程并且不是application
                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) {
            // Either an application context or we're on a background thread.
            //全局的context 或者 子线程
            if (applicationManager == null) {
                synchronized (this) {
                    if (applicationManager == null) {
                        // Normally pause/resume is taken care of by the fragment we add to the fragment or activity.
                        // However, in this case since the manager attached to the application will not receive lifecycle
                        // events, we must force the manager to start resumed using ApplicationLifecycle.
                        applicationManager = new RequestManager(context.getApplicationContext(),
                                new ApplicationLifecycle(), new EmptyRequestManagerTreeNode());
                    }
                }
            }
    
            return applicationManager;
        }
    

    //子线程 或者 Android 3.0 用全局的Context ,因为application的生命周期和Glide一样,否则创建fragment来监听activity的生命周期

    public class RequestManagerRetriever implements Handler.Callback {
     @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);
            }
        }
    
    
        @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);
                //TAG add一个没有界面的fragment
                    fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
                    handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
                }
            }
            return current;
        }
    }
    
    

    Glide.with(activity) 返回一个requestManager,with的参数决定图片的加载周期;
    若是application 那是和应用周期一样,若是fragment则创建一个无界面的fragment 的来绑定activity的生命周期

    load(url)

    public class RequestManager implements LifecycleListener {
       /**
         * Returns a request builder to load the given {@link java.lang.String}.
         * signature.
         *
         * @see #fromString()
         * @see #load(Object)
         *
         * @param string A file path, or a uri or url handled by {@link com.bumptech.glide.load.model.UriLoader}.
         */
        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<T, InputStream> streamModelLoader = Glide.buildStreamModelLoader(modelClass, context);
            ModelLoader<T, ParcelFileDescriptor> 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<T>(modelClass, streamModelLoader, fileDescriptorModelLoader, context,
                            glide, requestTracker, lifecycle, optionsApplier));
        }
    }
    
    
    public class DrawableRequestBuilder<ModelType>
            extends GenericRequestBuilder<ModelType, ImageVideoWrapper, GifBitmapWrapper, GlideDrawable>
            implements BitmapOptions, DrawableOptions {
    
        @Override
        public DrawableRequestBuilder<ModelType> load(ModelType model) {
            super.load(model);
            return this;
        }
    }
    
    

    into(imageView);

    public class DrawableRequestBuilder<ModelType>
            extends GenericRequestBuilder<ModelType, ImageVideoWrapper, GifBitmapWrapper, GlideDrawable>
            implements BitmapOptions, DrawableOptions {
       @Override
        public Target<GlideDrawable> into(ImageView view) {
            return super.into(view);
        }
    }
    
    
    public class GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> implements Cloneable {
      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) {
                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));
        }
    }
    
    public class GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> implements Cloneable {
      /**
         * Set the target the resource will be loaded into.
         *
         * @see Glide#clear(com.bumptech.glide.request.target.Target)
         *
         * @param target The target to load the resource into.
         * @return The given target.
         */
        public <Y extends Target<TranscodeType>> Y into(Y target) {
            Util.assertMainThread();
              //GlideDrawableImageViewTarget
            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.runRequest(request);
    
            return target;
        }
    }
    
    
    public class GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> implements Cloneable {
          private Request buildRequest(Target<TranscodeType> target) {
            if (priority == null) {
                priority = Priority.NORMAL;
            }
            return buildRequestRecursive(target, null);
        }
    
        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);
        }
    
    }
    
    
    public final class GenericRequest<A, T, Z, R> implements Request, SizeReadyCallback,
            ResourceCallback {
         
        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,
                    signature,
                    context,
                    priority,
                    target,
                    sizeMultiplier,
                    placeholderDrawable,
                    placeholderResourceId,
                    errorDrawable,
                    errorResourceId,
                    fallbackDrawable,
                    fallbackResourceId,
                    requestListener,
                    requestCoordinator,
                    engine,
                    transformation,
                    transcodeClass,
                    isMemoryCacheable,
                    animationFactory,
                    overrideWidth,
                    overrideHeight,
                    diskCacheStrategy);
            return request;
        }
    }
    
    public class GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> implements Cloneable {
    public <Y extends Target<TranscodeType>> Y into(Y target) {
        if (target == null) {
        t request = buildRequest(target);
        target.setRequest(request);
        lifecycle.addListener(target);
        requestTracker.runRequest(request);
        return target;
      }
    }
    
    
    public class RequestTracker {
      /**
         * Starts tracking the given request.
         */
        public void runRequest(Request request) {
            requests.add(request);
            //判断是否暂停状态,若不是调用begin,若是添加到执行队列,等待不是暂停状态在执行
            if (!isPaused) {
                //GenericRequest
                request.begin();
            } else {
                pendingRequests.add(request);
            }
        }
    
    }
    
    
    
    public final class GenericRequest<A, T, Z, R> implements Request, SizeReadyCallback,
            ResourceCallback {
       @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 源码分析(Version_3.7.0)

          本文链接:https://www.haomeiwen.com/subject/kmskzqtx.html