Glide 源码分析

来源:互联网 发布:英语造句软件下载 编辑:程序博客网 时间:2024/06/06 19:21

闲来无事,就按照代码的调用方式来分析下Glide的源码,顺便方便自己以后翻看(水平有点低,欢迎留言)。

首先,我们先分析下一般的加载图片的工具类需要具有 的功能:

1、需要使用双缓存机制,对图片进行本地和内存的存储;

2、需要使用多线程对网上的图片进行下载,还需要根据需求进行裁剪;

3、需要UI线程和下载线程的交流,从而实现加载图片的要求。

4、还要考虑加载图片的一些内存回收;

姑且只能想到这4点。

一、  我们一般调用的方式是:

//使用Glide加载网络图片public static void showImageWithGlide(Context context, final CircleImageView imageView, final String url) {    imageView.setTag(url);    Glide.with(context)            .load(url)            .placeholder(R.drawable.login_pho)            .into(new SimpleTarget<GlideDrawable>() {                @Override                public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> glideAnimation) {                    if(url.equals((String)imageView.getTag())) {                        imageView.setImageDrawable(resource);                    }                }            });}

这个是我们项目中的一段代码。

二、我们来看Glide.with(context)

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

这里用到了RequestManagerRetriever这个类,看代码的解释

这个类是一个创建新RequestManager的工具类,其中RequestManager需要Context这个变量,因此可以猜测retriever.get(context)中实现了RequestManager

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)) {        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);}
这个是get代码这里只是一个封装类,将各种Context的情况进行了打包,我们选择get((Activity)context)进行跟踪。(其实这里我们一般写的时候,不是写在UI线程中的)

@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);    }}
这里呢,判断是不是在UI线程中,

1.如果是在UI线程中的时候呢,会调用FragmentGet函数,这里没搞懂,为啥在UI线程的时候就一定有fragment?

2.如果不是在UI线程的话,就直接调用getApplicationManger了

反正这两个最终是获得了RequestManager了,感觉说的啰嗦了。

RequestManager是一个可以管理和开始Request的类。

然后是load方法@RequestManager

public DrawableTypeRequest<String> load(String string) {    return (DrawableTypeRequest<String>) fromString().load(string);}
1、fromString()方法

public DrawableTypeRequest<String> fromString() {    return loadGeneric(String.class);}
其实可以猜测就是根据不同的参数,采用不同的加载策略,先不考虑,先看下DrawableTypeRequest,这个类是用来创建一个load request,可以加载gif亦可以加载bitmap文件。

public class DrawableTypeRequest<ModelType> extends DrawableRequestBuilder<ModelType> implements DownloadOptions
其中load是在builder中的

最后在GenericRequestBuilder中的load方法中,将其放到model中

public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> load(ModelType model) {    this.model = model;    isModelSet = true;    return this;}
然后是下一个流程:

public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> placeholder(        int resourceId) {    this.placeholderId = resourceId;    return this;}
placeHolder的作用是
Sets an Android resource id for a {@link android.graphics.drawable.Drawable} resourceto display while a resource* is loading.

然后看into方法

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();    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;}
看下buildRequest,然后会调用buildRequestRecursive

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);    }}
好吧  这个下面再讨论,略复杂

0 0