您的当前位置:首页正文

Glide源码解析(1)—图片加载流程

2024-11-29 来源:个人技术集锦

Glide加载图片主流程分析

Glide版本:3.7.0

使用Glide的时候主要三步代码,如下所示:

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

Glide.with(this)

获取一个RequestManager对象

public static RequestManager with(Activity activity) {
   
    // 饿汉式 单例模式创建
    RequestManagerRetriever retriever = RequestManagerRetriever.get();
    // 获取一个RequestManager对象
    return retriever.get(activity);
}

RequestManager

RequestManager类的注释是:A class for managing and starting requests for Glide,意思是一个为Glide管理和开启请求的类。

load方法:

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

fromString方法:

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

loadGeneric方法,就是负责创建DrawableTypeRequest对象,泛型是String类型。

最终调用的是DrawableTypeRequest类的load方法。

DrawableTypeRequest

load方法:

@Override
public DrawableRequestBuilder<ModelType> load(ModelType model) {
    super.load(model);
    return this;
}

调用了父类GenericRequestBuilder的load方法:

GenericRequestBuilder类load方法:

public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> load(ModelType model) {
    this.model = model;
    isModelSet = true;
    return this;
}

这里其实就是将参数传递进来,整个流程相当于只是配置了一下加载的参数。

into(view)流程

点进去into方法,进入DrawableRequestBuilder类的into方法,这里调用了父类的into方法。

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

进入父类GenericRequestBuilder类的into方法:

public Target<TranscodeType> into(ImageView view) {
    Util.assertMainThread(); // 保证在主线程执行
   	// 省略部分代码
   	......
    return into(glide.buildImageViewTarget(view, transcodeClass));
}

这里首先调用了buildImageViewTarget方法:

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

这里通过一个工厂创建Target,ImageViewTargetFactory在glide创建的时候就创建了。

 private final ImageViewTargetFactory imageViewTargetFactory = new ImageViewTargetFactory();

这里顺便看一下ImageViewTargetFactory工厂:

public class ImageViewTargetFactory {
   

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

这里会根据条件分别创建GlideDrawableImageViewTargetBitmapImageViewTargetDrawableImageViewTarget

回到into方法,

    public <Y extends Target<TranscodeType>> Y into(Y target) {
   
        // 判断当前请求状态
        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;
    }

这里最后主要调用了requestTracker.runRequest(request);方法。

进入RequestTracker类的runRequest方法:

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

RequestTracker类有个Set集合存储请求,有个List集合存储等待请求,这个后续研究。

进入request.begin();方法,会进入Request 的接口类,找到其实现类GenericRequest类:

    @Override
    public void begin() {
   
        ......
        status = Status.WAITING_FOR_SIZE;
        if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
   
            // 确定好图片大小之后,开始处理
            onSizeReady(overrideWidth, overrideHeight);
        } else {
   
            target.getSize(this);
        }

        if (!isComplete() && !isFailed() && canNotifyStatusChanged
显示全文