Glide 源码分析

闲来无事,就按照代码的调用方式来分析下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);
    }
}
好吧  这个下面再讨论,略复杂

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值