Glide 支持类型 model
index | type | example |
---|---|---|
1 | Bitmap | |
2 | Drawable | |
3 | String | |
4 | Uri | |
5 | File | |
6 | URL | |
7 | Integer | |
8 | byte[] | |
9 | Object |
在 Activity 中,一行代码可实现图片加载。
GlideApp.with(this).load(url).into(imageView);
三个方法,参数,context,url 和 view。
GlideApp 、GlideRequests,GlideRequest 类,编译自动生成。
with() 方法,生成 GlideRequests。
load() 方法,生成 GlideRequest。
一、with() 方法
1,with() 方法支持多个参数类型。
返回 GlideRequests 对象,父类 RequestManager。
//GlideApp的with()方法。
public static GlideRequests with(@NonNull View arg0) {
return (GlideRequests) Glide.with(arg0);
}
//这些方法都会调用Glide的with()方法,参数也支持。
//Glide的with方法。
public static RequestManager with(@NonNull View view) {
return getRetriever(view.getContext()).get(view);
}
2,生成 RequestManager
Glide 类内部 RequestManagerRetriever,维护 context 和 RequestManager 的关系,负责生成 GlideRequests ( RequestManager ),同时发起多个请求使用同一个 GlideRequests,和同一个上下文 Activity / Fragment 相关的请求。
#RequestManagerRetriever类get()方法。
public RequestManager get(@NonNull View view) {
//非主线程
if (Util.isOnBackgroundThread()) {
return get(view.getContext().getApplicationContext());
}
Activity activity = findActivity(view.getContext());
if (activity == null) {
return get(view.getContext().getApplicationContext());
}
if (activity instanceof FragmentActivity) {
Fragment fragment = findSupportFragment(view, (FragmentActivity) activity);
return fragment != null ? get(fragment) : get(activity);
}
android.app.Fragment fragment = findFragment(view, activity);
if (fragment == null) {
return get(activity);
}
return get(fragment);
}
get() 方法,支持多个参数。
参数 View 类型时,非主线程或 View 上下文 Activity 是空,由全局 ApplicationContext 加载,其他情况,解析 View 对应 Fragment 或 Activity 加载。
参数 Context 时,判断具体类型 Fragment、Activity、FragmentActivity。
最终,有三个地方通过工厂模式创建 RequestManager。全局 Context,获取它内部的 RequestManager 对象。
fragmentGet() 方法,支持普通 Fragment 和 Activity
supportFragmentGet() 方法,支持 (support-v4) FragmentActivity 和 (support-v4) Fragment。
子类 RequestManagerFragment 和 SupportRequestManagerFragment。
将当前 Activity 新增一个 Fragment,将 RequestManager 绑定内部。
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
复用 Fragment 绑定的 RequestManager。
fm.findFragmentByTag(FRAGMENT_TAG)
当参数Context上下文和Activity组件无关时,统一使用全局RequestManager,即applicationManager。
@NonNull
private RequestManager supportFragmentGet(@NonNull Context context, @NonNull FragmentManager fm,
@Nullable Fragment parentHint) {
//parentHint是加载图片的那个Fragment。
SupportRequestManagerFragment current = getSupportRequestManagerFragment(fm, parentHint);
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
Glide glide = Glide.get(context);
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
current.setRequestManager(requestManager);
}
return requestManager;
}
创建的 RequestManager 对象保存 SupportRequestManagerFragment,空时才会创建。
RequestManagerFactory 工厂创建 RequestManager,在 GlideBuilder 类中,最后在 build() 方法时,保存在 RequestManagerRetriever 内部。
GeneratedRequestManagerFactory 工厂类是自动生成的 Java 类,实现了抽象工厂接口 RequestManagerFactory。
@Override
GeneratedRequestManagerFactory getRequestManagerFactory() {
return new GeneratedRequestManagerFactory();
}
final class GeneratedRequestManagerFactory implements RequestManagerRetriever.RequestManagerFactory {
@Override
public RequestManager build(Glide glide, Lifecycle lifecycle, RequestManagerTreeNode treeNode,
Context context) {
return new GlideRequests(glide, lifecycle, treeNode, context);
}
}
该工厂创建一个 GlideRequests 对象,继承 RequestManager。在 GlideApp 的 with() 方法,将它转换成 GlideRequests 对象。
综上,with() 方法,根据当前请求的组件或视图上下文,返回一个请求实体管理者 GlideRequests。
二、load() 方法
GlideRequests 管理对象对 load() 方法,生成 GlideRequest,支持多种类型数据源入参。
通过 url ( String 类型) 参数进行解析 GlideRequests 的 load() 方法。
//GlideRequests方法
public GlideRequest<Drawable> load(@Nullable String arg0) {
return (GlideRequest<Drawable>) super.load(arg0);
}
父类 RequestManager 的 load() 方法。
//RequestManager方法
public RequestBuilder<Drawable> load(@Nullable String string) {
return asDrawable().load(string);
}
asDrawable() 方法,负责创建 RequestBuilder 对象,代表一个具体请求,支持不同类型,如 asBitmap(),asFile()。as() 方法,参数不同。
public RequestBuilder<Drawable> asDrawable() {
return as(Drawable.class);
}
public <ResourceType> RequestBuilder<ResourceType> as(
@NonNull Class<ResourceType> resourceClass) {
return new RequestBuilder<>(glide, this, resourceClass, context);
}
GlideRequests 类重写了 as() 方法。
因此,GlideRequests 的 load() 方法,创建的是 RequestBuilder 子类,即GlideRequest 对象,强制类型转换。
asDrawable() 方法,资源类型 <ResourceType> 是 Drawable 类,请求实体内部最终需要转换的资源类型,即 transcodeClass。
load() 方法。
public RequestBuilder<TranscodeType> load(@Nullable String string) {
return loadGeneric(string);
}
String 类型的 url,调用通用 loadGeneric() 方法。
@NonNull
private RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model){
this.model = model;
isModelSet = true;
return this;
}
保存加载资源 model,该示例保存 String 类型 url。
load() 方法,根据请求资源类型,由 GlideRequests 管理者创建一个具体的GlideRequest 请求实体。
三、into() 方法
GlideRequest<Drawable> 的 into() 方法,父类 RequestBuilder 的 into() 方法,参数 ImageView 对象。
public ViewTarget<ImageView, TranscodeType> into(ImageView view) {
RequestOptions requestOptions = this.requestOptions;
if (!requestOptions.isTransformationSet()
&& requestOptions.isTransformationAllowed()
&& view.getScaleType() != null) {
switch (view.getScaleType()) {
case CENTER_CROP:
requestOptions = requestOptions.clone().optionalCenterCrop();
break;
case CENTER_INSIDE:
requestOptions = requestOptions.clone().optionalCenterInside();
break;
...//ScaleType类型判断,其他类型相关代码省略。
}
}
return into(
glideContext.buildImageViewTarget(view, transcodeClass),
/*targetListener=*/ null,
requestOptions);
}
根据 ImageView 的 ScaleType 类型,设置 RequestOptions 配置项。
ImageView 和 Class<TranscodeType> 即 as() 的入参。
GlideContext 的 buildImageViewTarget() 方法,创建 ViewTarget<ImageView, X>。
GlideContext 内部 ImageViewTargetFactory工厂类。
根据 Class<TranscodeType> transcodeClasss,创建 ViewTarget 有两种类型。
transcodeClasss 类型,即 as() 方法的入参,RequestBuilder 对象构造方法参数。
创建 ViewTarget 后,调用另一个 into() 方法。
private <Y extends Target<TranscodeType>> Y into(
@NonNull Y target,
@Nullable RequestListener<TranscodeType> targetListener,
@NonNull RequestOptions options) {
//在into之前,调用load方法设置model,并设置isModelSet为true。
if (!isModelSet) {
throw new IllegalArgumentException("You must call #load() before calling #into()");
}
options = options.autoClone();
Request request = buildRequest(target, targetListener, options);
...
requestManager.clear(target);
target.setRequest(request);
requestManager.track(target, request);
return target;
}
buildRequest() 方法,创建一个 Request 请求,Request 是一个接口,表示目标 Target 加载资源的请求,绑定 ViewTarget 内部。
RequestManager 请求管理器,清理。
Target 绑定 Request,调用请求管理器的 track 方法,每个请求实体都引用 RequestManager,RequestBuilder 构造方法传入。
void track(Target<?> target, Request request) {
targetTracker.track(target);
requestTracker.runRequest(request);
}
TargetTracker 类维护一个 Target 集合,调用 RequestTracker 的 runRequest() 方法,监听 Glide Fragment 生命周期 LifecycleListener。
public void runRequest(Request request) {
requests.add(request);
if (!isPaused) {
request.begin();
} else {
pendingRequests.add(request);
}
}
RequestTracker 追踪器,管理请求集合,请求加入内部 Set 集合,根据暂停状态,调用 SingleRequest 的 begin() 方法,开始,或 pendingRequests 加入等待列表。
开始请求数据,Request 的 begin() 方法。
public void begin() {
startTime = LogTime.getLogTime();
if (model == null) {
...
onLoadFailed(new GlideException("Received null model"), logLevel);
return;
}
if (status == Status.RUNNING) {
throw new IllegalArgumentException("Cannot restart a running request");
}
if (status == Status.COMPLETE) {
onResourceReady(resource, DataSource.MEMORY_CACHE);
return;
}
status = Status.WAITING_FOR_SIZE;
if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
onSizeReady(overrideWidth, overrideHeight);
} else {
target.getSize(this);
}
if ((status == Status.RUNNING || status == Status.WAITING_FOR_SIZE)
&& canNotifyStatusChanged()) {
target.onLoadStarted(getPlaceholderDrawable());
}
}
创建 RequestBuilder<Drawable> 时,将加载资源 (网络是 url )保存在内部 model 对象,obtain() 方法 创建 SingleRequest,初始化 包括 model 参数。
状态 WAITING_FOR_SIZE , 判断 size 是否准备好,Target 的 getSize() 方法,准备宽高。
SizeReadyCallback 接口 , onSizeReady() 方法中进行 load 加载。
public void onSizeReady(int width, int height) {
stateVerifier.throwIfRecycled();
//状态必须是WAITING_FOR_SIZE。
if (status != Status.WAITING_FOR_SIZE) {
return;
}
status = Status.RUNNING;//状态更新RUNNING
float sizeMultiplier = requestOptions.getSizeMultiplier();
this.width = maybeApplySizeMultiplier(width, sizeMultiplier);
this.height = maybeApplySizeMultiplier(height, sizeMultiplier);
loadStatus = engine.load(
glideContext,
model,
requestOptions.getSignature(),
this.width,
this.height,...);//load参数较多
if (status != Status.RUNNING) {
loadStatus = null;
}
}
改变 RUNNING 状态。
通过 SingleRequest 内部加载引擎 Engine,load() 方法加载,返回一个状态 LoadStatus,参数多是请求配置参数。
每次图片加载请求,创建一个 SingleRequest,加载引擎 Engine 对象通用。
任重而道远