Glide源码阅读之建造者(builder)模式3【RequestOptions】【BaseRequestOptions】
前几篇builder模式应用
Glide多种组合使用方式记录–没有全部亲测,大家可以根据实际需要选用
Glide设计模式之建造者(builder)模式1【GlideBuilder】
Glide设计模式之建造者(builder)模式2【RequestBuilder】
Glide设计模式之建造者(builder)模式3【RequestOptions】【BaseRequestOptions】
Glide设计模式之建造者(builder)模式4总结【MemorySizeCalculator】【GlideExecutor】【PreFillType】【LazyHeaders】
官方定义
本来解析完GlideBuilder、RequestBuilder就已经觉得建造者模式用的变化有些大了,但随着解析的进行发现还要下面的这两种变种应用。先解析出来给大家看看,说不定在某些场景下能启发读者使用这种模式应用方式
builder模式应用变化一
结构:
public static RequestOptions sizeXXXX(parameters…){return new RequestOptions(parameters…) }
/**
* Provides type independent options to customize loads with Glide.
*
* <p>Non-final to allow Glide's generated classes to be assignable to their non-generated
* equivalents.
*/
提供类型独立选项,以自定义加载与Glide。
非final,允许Glide生成的类可以赋值给它们的非生成的等价物。
@SuppressWarnings("PMD.UseUtilityClass")
public class RequestOptions extends BaseRequestOptions<RequestOptions> {
@Nullable private static RequestOptions skipMemoryCacheTrueOptions;
@Nullable private static RequestOptions skipMemoryCacheFalseOptions;
@Nullable private static RequestOptions fitCenterOptions;
@Nullable private static RequestOptions centerInsideOptions;
@Nullable private static RequestOptions centerCropOptions;
@Nullable private static RequestOptions circleCropOptions;
@Nullable private static RequestOptions noTransformOptions;
@Nullable private static RequestOptions noAnimationOptions;
/** Returns a {@link RequestOptions} object with {@link #sizeMultiplier(float)} set. */
返回设置了BaseRequestOptions.sizeMultiplier(float)的RequestOptions对象。
@SuppressWarnings("WeakerAccess") // Public API
@NonNull
@CheckResult
public static RequestOptions sizeMultiplierOf(
@FloatRange(from = 0, to = 1) float sizeMultiplier) {
return new RequestOptions().sizeMultiplier(sizeMultiplier);
}
/**
* Returns a {@link RequestOptions} object with {@link #diskCacheStrategy(DiskCacheStrategy)} set.
*/
返回一个设置了BaseRequestOptions.diskCacheStrategy(DiskCacheStrategy)的RequestOptions对象。
@NonNull
@CheckResult
public static RequestOptions diskCacheStrategyOf(@NonNull DiskCacheStrategy diskCacheStrategy) {
return new RequestOptions().diskCacheStrategy(diskCacheStrategy);
}
/**
* Returns a {@link RequestOptions} object with {@link BaseRequestOptions#priority(Priority)}}
* set.
*/
返回一个设置了BaseRequestOptions.priority(Priority)}的RequestOptions对象。
@SuppressWarnings("WeakerAccess") // Public API
@NonNull
@CheckResult
public static RequestOptions priorityOf(@NonNull Priority priority) {
return new RequestOptions().priority(priority);
}
/** Returns a {@link RequestOptions} object with {@link #placeholder(Drawable)} set. */
返回一个带有BaseRequestOptions.placeholder(Drawable)设置的RequestOptions对象。
@NonNull
@CheckResult
public static RequestOptions placeholderOf(@Nullable Drawable placeholder) {
return new RequestOptions().placeholder(placeholder);
}
/** Returns a {@link RequestOptions} object with {@link #placeholder(int)} set. */
@NonNull
@CheckResult
public static RequestOptions placeholderOf(@DrawableRes int placeholderId) {
return new RequestOptions().placeholder(placeholderId);
}
/** Returns a {@link RequestOptions} object with {@link #error(Drawable)} set. */
@NonNull
@CheckResult
public static RequestOptions errorOf(@Nullable Drawable errorDrawable) {
return new RequestOptions().error(errorDrawable);
}
/** Returns a {@link RequestOptions} object with {@link #error(int)}} set. */
@NonNull
@CheckResult
public static RequestOptions errorOf(@DrawableRes int errorId) {
return new RequestOptions().error(errorId);
}
/** Returns a {@link RequestOptions} object with {@link #skipMemoryCache(boolean)} set. */
@NonNull
@CheckResult
public static RequestOptions skipMemoryCacheOf(boolean skipMemoryCache) {
。。。
}
/** Returns a {@link RequestOptions} object with {@link #override(int, int)}} set. */
@SuppressWarnings("WeakerAccess") // Public API
@NonNull
@CheckResult
public static RequestOptions overrideOf(int width, int height) {
return new RequestOptions().override(width, height);
}
/**
* Returns a {@link RequestOptions} with {@link #override(int, int)} set where both the width and
* height are the given size.
*/
返回一个带有BaseRequestOptions的RequestOptions。覆盖(int, int)设置的宽度和高度都是给定的大小。
@SuppressWarnings("WeakerAccess") // Public API
@NonNull
@CheckResult
public static RequestOptions overrideOf(int size) {
return overrideOf(size, size);
}
/** Returns a {@link RequestOptions} object with {@link #signature} set. */
@NonNull
@CheckResult
public static RequestOptions signatureOf(@NonNull Key signature) {
return new RequestOptions().signature(signature);
}
/** Returns a {@link RequestOptions} object with {@link #fitCenter()} set. */
@NonNull
@CheckResult
public static RequestOptions fitCenterTransform() {
。。。
}
/** Returns a {@link RequestOptions} object with {@link #centerInside()} set. */
@SuppressWarnings("WeakerAccess") // Public API
@NonNull
@CheckResult
public static RequestOptions centerInsideTransform() {
。。。
}
/** Returns a {@link RequestOptions} object with {@link #centerCrop()} set. */
@SuppressWarnings("WeakerAccess") // Public API
@NonNull
@CheckResult
public static RequestOptions centerCropTransform() {
。。。
}
/** Returns a {@link RequestOptions} object with {@link RequestOptions#circleCrop()} set. */
@SuppressWarnings("WeakerAccess") // Public API
@NonNull
@CheckResult
public static RequestOptions circleCropTransform() {
。。。
}
/** Returns a {@link RequestOptions} object with {@link #transform(Transformation)} set. */
@SuppressWarnings("WeakerAccess") // Public API
@NonNull
@CheckResult
public static RequestOptions bitmapTransform(@NonNull Transformation<Bitmap> transformation) {
return new RequestOptions().transform(transformation);
}
/** Returns a {@link RequestOptions} object with {@link #dontTransform()} set. */
@SuppressWarnings("WeakerAccess")
@NonNull
@CheckResult
public static RequestOptions noTransformation() {
。。。
}
/**
* Returns a {@link RequestOptions} object with the given {@link Option} set via {@link
* #set(Option, Object)}.
*/
@NonNull
@CheckResult
public static <T> RequestOptions option(@NonNull Option<T> option, @NonNull T value) {
return new RequestOptions().set(option, value);
}
/** Returns a {@link RequestOptions} object with {@link #decode(Class)} set. */
@NonNull
@CheckResult
public static RequestOptions decodeTypeOf(@NonNull Class<?> resourceClass) {
return new RequestOptions().decode(resourceClass);
}
/** Returns a {@link RequestOptions} object with {@link #format(DecodeFormat)} set. */
@SuppressWarnings("WeakerAccess") // Public API
@NonNull
@CheckResult
public static RequestOptions formatOf(@NonNull DecodeFormat format) {
return new RequestOptions().format(format);
}
/** Returns a {@link RequestOptions} object with {@link #frame(long)} set. */
@SuppressWarnings("WeakerAccess") // Public API
@NonNull
@CheckResult
public static RequestOptions frameOf(@IntRange(from = 0) long frameTimeMicros) {
return new RequestOptions().frame(frameTimeMicros);
}
/** Returns a {@link RequestOptions} object with {@link #downsample(DownsampleStrategy)} set. */
@SuppressWarnings("WeakerAccess") // Public API
@NonNull
@CheckResult
public static RequestOptions downsampleOf(@NonNull DownsampleStrategy strategy) {
return new RequestOptions().downsample(strategy);
}
/** Returns a {@link RequestOptions} object with {@link #timeout(int)} set. */
@NonNull
@CheckResult
public static RequestOptions timeoutOf(@IntRange(from = 0) int timeout) {
return new RequestOptions().timeout(timeout);
}
/**
* Returns a {@link com.bumptech.glide.request.RequestOptions} with {@link #encodeQuality(int)}
* called with the given quality.
*/
@SuppressWarnings("WeakerAccess") // Public API
@NonNull
@CheckResult
public static RequestOptions encodeQualityOf(@IntRange(from = 0, to = 100) int quality) {
return new RequestOptions().encodeQuality(quality);
}
/**
* Returns a {@link com.bumptech.glide.request.RequestOptions} with {@link
* #encodeFormat(android.graphics.Bitmap.CompressFormat)} called with the given format.
*/
@SuppressWarnings("WeakerAccess") // Public API
@NonNull
@CheckResult
public static RequestOptions encodeFormatOf(@NonNull Bitmap.CompressFormat format) {
return new RequestOptions().encodeFormat(format);
}
/**
* Returns a new {@link com.bumptech.glide.request.RequestOptions} with {@link #dontAnimate()}
* called.
*/
@SuppressWarnings("WeakerAccess") // Public API
@NonNull
@CheckResult
public static RequestOptions noAnimation() {
if (noAnimationOptions == null) {
noAnimationOptions = new RequestOptions().dontAnimate().autoClone();
}
return noAnimationOptions;
}
这样全部都是静态且具体过程都是new对象的方式,挺少见的。也是因为参数比较多比较繁琐。而且都是可定制的。这个看上去像一个生产工厂似的不过也是因为使用场景的不同而进行了结构变化。不过从中可以看出builder模式和工厂模式的结合使用。如果只有一个也许看不出来两种模式结合使用。如此多的相同的静态返回且都是类本身就很明显了。再加上不同的参数,有些工厂模式的感觉但没有工厂模式的痕迹。
咱们接着看下一个,这个也是我碰到比较BT的建造者模式应用变化了
builder模式应用变化二
包路径:com.bumptech.glide.request.BaseRequestOptions
结构
public T xxxx(float sizeMultiplier){
return selfOrThrowIfLocked();
}
T:泛型返回作为建造者模式来使用。还是如此多参数设置和自定义情况下。
在结合RequestOptions类实现情况下又有原型模式的影子。
这帮Glide贡献者大神把设计模式应用变化多端是真S(和谐文字)啊!
/**
* A base object to allow method sharing between {@link RequestOptions} and {@link
* com.bumptech.glide.RequestBuilder}.
*
* <p>This class is not meant for general use and may change at any time.
*
* @param <T> The particular child implementation
*/
一个基对象,允许RequestOptions和RequestBuilder之间共享方法。
这个类不适合一般使用,可以随时更改。
类型参数:
T -特定的子实现
@SuppressWarnings({"PMD.UseUtilityClass", "unused"})
public abstract class BaseRequestOptions<T extends BaseRequestOptions<T>> implements Cloneable {
。。。
/**
* Applies a multiplier to the {@link com.bumptech.glide.request.target.Target}'s size before
* loading the resource. Useful for loading thumbnails or trying to avoid loading huge resources
* (particularly {@link Bitmap}s on devices with overly dense screens.
*
* @param sizeMultiplier The multiplier to apply to the {@link
* com.bumptech.glide.request.target.Target}'s dimensions when loading the resource.
* @return This request builder.
*/
在加载资源之前,将乘数应用到目标的大小。对于加载缩略图或试图避免加载大量资源(特别是在屏幕过于密集的设备上的位图)很有用。
参数:
sizeMultiplier -加载资源时应用于目标维度的乘法器。
返回:
这个请求构建器。
@NonNull
@CheckResult
public T sizeMultiplier(@FloatRange(from = 0, to = 1) float sizeMultiplier) {
if (isAutoCloneEnabled) {
return clone().sizeMultiplier(sizeMultiplier);
}
if (sizeMultiplier < 0f || sizeMultiplier > 1f) {
throw new IllegalArgumentException("sizeMultiplier must be between 0 and 1");
}
this.sizeMultiplier = sizeMultiplier;
fields |= SIZE_MULTIPLIER;
return selfOrThrowIfLocked();
}
/**
* If set to {@code true}, uses a cached unlimited {@link java.util.concurrent.Executor} to run
* the request.
*
* <p>This method should <em>ONLY</em> be used when a Glide load is started recursively on one of
* Glide's threads as part of another request. Using this method in other scenarios can lead to
* excessive memory usage and OOMs and/or a significant decrease in performance across an
* application.
*
* <p>If both this method and {@link #useAnimationPool(boolean)} are set, this method will be
* preferred and {@link #useAnimationPool(boolean)} will be ignored.
*/
如果设置为true,则使用缓存的无限Executor来运行请求。
当一个Glide加载作为另一个请求的一部分在其中一个Glide线程上递归启动时,才应该使用此方法。在其他场景中使用这种方法可能会导致过度的内存使用和OOMs,以及/或整个应用程序的性能显著下降。
如果同时设置了这个方法和useAnimationPool(boolean),则该方法将被首选,而useAnimationPool(boolean)将被忽略。
@NonNull
@CheckResult
public T useUnlimitedSourceGeneratorsPool(boolean flag) {
if (isAutoCloneEnabled) {
return clone().useUnlimitedSourceGeneratorsPool(flag);
}
this.useUnlimitedSourceGeneratorsPool = flag;
fields |= USE_UNLIMITED_SOURCE_GENERATORS_POOL;
return selfOrThrowIfLocked();
}
/**
* If set to {@code true}, uses a special {@link java.util.concurrent.Executor} that is used
* exclusively for decoding frames of animated resources, like GIFs.
*
* <p>The animation executor disallows network operations and must not be used for loads that may
* load remote data. The animation executor has fewer threads available to it than Glide's normal
* executors and is only useful as a way of avoiding blocking on longer and more expensive reads
* for critical requests like those in an animating GIF.
*
* <p>If both {@link #useUnlimitedSourceGeneratorsPool(boolean)} and this method are set, {@link
* #useUnlimitedSourceGeneratorsPool(boolean)} will be preferred and this method will be ignored.
*/
如果设置为true,则使用一个特殊的Executor,它专门用于解码动画资源的帧,比如gif。
动画执行器禁止网络操作,并且不能用于可能加载远程数据的加载。与Glide的普通执行程序相比,动画执行程序可用的线程更少,并且只能用于避免在读取关键请求时阻塞,比如GIF动画。
如果useUnlimitedSourceGeneratorsPool(boolean)和这个方法都设置了,useUnlimitedSourceGeneratorsPool(boolean)将被首选,这个方法将被忽略。
@NonNull
@CheckResult
public T useAnimationPool(boolean flag) {
if (isAutoCloneEnabled) {
return clone().useAnimationPool(flag);
}
useAnimationPool = flag;
fields |= USE_ANIMATION_POOL;
return selfOrThrowIfLocked();
}
/**
* If set to true, will only load an item if found in the cache, and will not fetch from source.
*/
如果设置为true,将只加载在缓存中找到的项,而不会从源文件中获取。
@NonNull
@CheckResult
public T onlyRetrieveFromCache(boolean flag) {
if (isAutoCloneEnabled) {
return clone().onlyRetrieveFromCache(flag);
}
this.onlyRetrieveFromCache = flag;
fields |= ONLY_RETRIEVE_FROM_CACHE;
return selfOrThrowIfLocked();
}
/**
* Sets the {@link DiskCacheStrategy} to use for this load.
*
* <p>Defaults to {@link DiskCacheStrategy#AUTOMATIC}.
*
* <p>For most applications {@link DiskCacheStrategy#RESOURCE} is ideal. Applications that use the
* same resource multiple times in multiple sizes and are willing to trade off some speed and disk
* space in return for lower bandwidth usage may want to consider using {@link
* DiskCacheStrategy#DATA} or {@link DiskCacheStrategy#ALL}.
*
* @param strategy The strategy to use.
* @return This request builder.
*/
设置此加载使用的DiskCacheStrategy。
默认为DiskCacheStrategy.AUTOMATIC。
对于大多数应用程序,DiskCacheStrategy。资源是理想的。如果应用程序以不同的大小多次使用相同的资源,并且愿意牺牲一些速度和磁盘空间来换取更低的带宽使用,那么可以考虑使用DiskCacheStrategy。数据或DiskCacheStrategy.ALL。
参数:
策略-使用的策略。
返回:
这个请求构建器。
@NonNull
@CheckResult
public T diskCacheStrategy(@NonNull DiskCacheStrategy strategy) {
if (isAutoCloneEnabled) {
return clone().diskCacheStrategy(strategy);
}
this.diskCacheStrategy = Preconditions.checkNotNull(strategy);
fields |= DISK_CACHE_STRATEGY;
return selfOrThrowIfLocked();
}
/**
* Sets the priority for this load.
*
* @param priority A priority.
* @return This request builder.
*/
设置此负载的优先级。
参数:
priority -优先级。
返回:
这个请求构建器。
@NonNull
@CheckResult
public T priority(@NonNull Priority priority) {
if (isAutoCloneEnabled) {
return clone().priority(priority);
}
this.priority = Preconditions.checkNotNull(priority);
fields |= PRIORITY;
return selfOrThrowIfLocked();
}
/**
* Sets an {@link Drawable} to display while a resource is loading.
*
* <p>Replaces any previous calls to this method or {@link #placeholder(int)}.
*
* @param drawable The drawable to display as a placeholder.
* @return This request builder.
*/
设置一个Drawable在资源加载时显示。
替换之前对该方法或占位符(int)的任何调用。
参数:
drawable—作为占位符显示的可绘制对象。
返回:
这个请求构建器。
@NonNull
@CheckResult
public T placeholder(@Nullable Drawable drawable) {
if (isAutoCloneEnabled) {
return clone().placeholder(drawable);
}
this.placeholderDrawable = drawable;
fields |= PLACEHOLDER;
placeholderId = 0;
fields &= ~PLACEHOLDER_ID;
return selfOrThrowIfLocked();
}
/**
* Sets an Android resource id for a {@link Drawable} resource to display while a resource is
* loading.
*
* <p>Replaces any previous calls to this method or {@link #placeholder(Drawable)}
*
* @param resourceId The id of the resource to use as a placeholder
* @return This request builder.
*/
设置一个可绘制资源的Android资源id,当资源加载时显示。
替换之前对该方法或占位符的任何调用(Drawable)
参数:
resourceId -要用作占位符的资源的id
返回:
这个请求构建器。
@NonNull
@CheckResult
public T placeholder(@DrawableRes int resourceId) {
if (isAutoCloneEnabled) {
return clone().placeholder(resourceId);
}
this.placeholderId = resourceId;
fields |= PLACEHOLDER_ID;
placeholderDrawable = null;
fields &= ~PLACEHOLDER;
return selfOrThrowIfLocked();
}
/**
* Sets an {@link Drawable} to display if the model provided to {@link
* com.bumptech.glide.RequestBuilder#load(Object)} is {@code null}.
*
* <p>If a fallback is not set, null models will cause the error drawable to be displayed. If the
* error drawable is not set, the placeholder will be displayed.
*
* <p>Replaces any previous calls to this method or {@link #fallback(int)}.
*
* @see #placeholder(Drawable)
* @see #placeholder(int)
* @param drawable The drawable to display as a placeholder.
* @return This request builder.
*/
设置Drawable在提供给RequestBuilder.load(Object)的模型为空时显示。
如果没有设置回退,则空模型将导致显示可绘制的错误。如果没有设置错误绘制,将显示占位符。
替换之前对该方法或fallback(int)的任何调用。
参数:
drawable—作为占位符显示的可绘制对象。
返回:
这个请求构建器
@NonNull
@CheckResult
public T fallback(@Nullable Drawable drawable) {
if (isAutoCloneEnabled) {
return clone().fallback(drawable);
}
this.fallbackDrawable = drawable;
fields |= FALLBACK;
fallbackId = 0;
fields &= ~FALLBACK_ID;
return selfOrThrowIfLocked();
}
/**
* Sets a resource to display if the model provided to {@link
* com.bumptech.glide.RequestBuilder#load(Object)} is {@code null}.
*
* <p>If a fallback is not set, null models will cause the error drawable to be displayed. If the
* error drawable is not set, the placeholder will be displayed.
*
* <p>Replaces any previous calls to this method or {@link #fallback(Drawable)}.
*
* @see #placeholder(Drawable)
* @see #placeholder(int)
* @param resourceId The id of the resource to use as a fallback.
* @return This request builder.
*/
设置一个资源,当提供给RequestBuilder.load(Object)的模型为空时显示该资源。
如果没有设置回退,则空模型将导致显示可绘制的错误。如果没有设置错误绘制,将显示占位符。
替换之前对该方法或回退(Drawable)的任何调用。
参数:
resourceId -用作回退的资源的id。
返回:
这个请求构建器。
@NonNull
@CheckResult
public T fallback(@DrawableRes int resourceId) {
if (isAutoCloneEnabled) {
return clone().fallback(resourceId);
}
this.fallbackId = resourceId;
fields |= FALLBACK_ID;
fallbackDrawable = null;
fields &= ~FALLBACK;
return selfOrThrowIfLocked();
}
/**
* Sets a {@link Drawable} to display if a load fails.
*
* <p>Replaces any previous calls to this method or {@link #error(int)}
*
* @param drawable The drawable to display.
* @return This request builder.
*/
设置一个Drawable在加载失败时显示。
替换之前对该方法的任何调用或错误(int)
参数:
drawable -可显示的图形。
返回:
这个请求构建器。
@NonNull
@CheckResult
public T error(@Nullable Drawable drawable) {
if (isAutoCloneEnabled) {
return clone().error(drawable);
}
this.errorPlaceholder = drawable;
fields |= ERROR_PLACEHOLDER;
this.errorId = 0;
fields &= ~ERROR_ID;
return selfOrThrowIfLocked();
}
/**
* Sets a resource to display if a load fails.
*
* <p>Replaces any previous calls to this method or {@link #error(Drawable)}
*
* @param resourceId The id of the resource to use as a placeholder.
* @return This request builder.
*/
设置在加载失败时显示的资源。
替换之前对该方法的调用或错误(Drawable)
参数:
resourceId -要用作占位符的资源的id。
返回:
这个请求构建器。
@NonNull
@CheckResult
public T error(@DrawableRes int resourceId) {
if (isAutoCloneEnabled) {
return clone().error(resourceId);
}
this.errorId = resourceId;
fields |= ERROR_ID;
this.errorPlaceholder = null;
fields &= ~ERROR_PLACEHOLDER;
return selfOrThrowIfLocked();
}
/**
* Sets the {@link android.content.res.Resources.Theme} to apply when loading {@link Drawable}s
* for resource ids provided via {@link #error(int)}, {@link #placeholder(int)}, and {@link
* #fallback(Drawable)}.
*
* <p>The theme is <em>NOT</em> applied in the decoder that will attempt to decode a given
* resource id model on Glide's background threads. The theme is used exclusively on the main
* thread to obtain placeholder/error/fallback drawables to avoid leaking Activities.
*
* <p>If the {@link android.content.Context} of the {@link android.app.Fragment} or {@link
* android.app.Activity} used to start this load has a different {@link
* android.content.res.Resources.Theme}, the {@link android.content.res.Resources.Theme} provided
* here will override the {@link android.content.res.Resources.Theme} of the {@link
* android.content.Context}.
*
* @param theme The theme to use when loading Drawables.
* @return this request builder.
*/
设置资源。当加载通过error(int),占位符(int),和fallback(Drawable)提供的资源id的Drawables时应用的主题。
这个主题没有应用到将尝试解码Glide后台线程上的给定资源id模型的解码器中。主题只在主线程上使用,以获取占位符/错误/回退绘图,以避免活动泄漏。
如果用于启动此加载的片段或活动的上下文有不同的资源。主题资源。这里提供的主题将覆盖参考资料。语境的主题。
参数:
在加载Drawables时使用的主题。
返回:
这个请求构建器。
@NonNull
@CheckResult
public T theme(@Nullable Resources.Theme theme) {
if (isAutoCloneEnabled) {
return clone().theme(theme);
}
this.theme = theme;
fields |= THEME;
return selfOrThrowIfLocked();
}
/**
* Allows the loaded resource to skip the memory cache.
*
* <p>Note - this is not a guarantee. If a request is already pending for this resource and that
* request is not also skipping the memory cache, the resource will be cached in memory.
*
* @param skip True to allow the resource to skip the memory cache.
* @return This request builder.
*/
允许加载的资源跳过内存缓存。
注意——这不是一个保证。如果一个请求已经在等待这个资源,并且这个请求也没有跳过内存缓存,那么这个资源将被缓存到内存中。
参数:
skip - True允许资源跳过内存缓存。
返回:
这个请求构建器。
@NonNull
@CheckResult
public T skipMemoryCache(boolean skip) {
if (isAutoCloneEnabled) {
return clone().skipMemoryCache(true);
}
this.isCacheable = !skip;
fields |= IS_CACHEABLE;
return selfOrThrowIfLocked();
}
/**
* Overrides the {@link com.bumptech.glide.request.target.Target}'s width and height with the
* given values. This is useful for thumbnails, and should only be used for other cases when you
* need a very specific image size.
*
* @param width The width in pixels to use to load the resource.
* @param height The height in pixels to use to load the resource.
* @return This request builder.
*/
用给定的值重写目标的宽度和高度。这对缩略图很有用,并且应该只在需要非常特定的图像大小的其他情况下使用。
参数:
width -用于加载资源的宽度(以像素为单位)。
height -用于加载资源的高度(以像素为单位)。
返回:
这个请求构建器。
@NonNull
@CheckResult
public T override(int width, int height) {
if (isAutoCloneEnabled) {
return clone().override(width, height);
}
this.overrideWidth = width;
this.overrideHeight = height;
fields |= OVERRIDE;
return selfOrThrowIfLocked();
}
/**
* Overrides the {@link com.bumptech.glide.request.target.Target}'s width and height with the
* given size.
*
* @see #override(int, int)
* @param size The width and height to use.
* @return This request builder.
*/
用给定的大小覆盖目标的宽度和高度。
参数:
size -使用的宽度和高度。
返回:
这个请求构建器。
@NonNull
@CheckResult
public T override(int size) {
return override(size, size);
}
/**
* Sets some additional data to be mixed in to the memory and disk cache keys allowing the caller
* more control over when cached data is invalidated.
*
* <p>Note - The signature does not replace the cache key, it is purely additive.
*
* @param signature A unique non-null {@link Key} representing the current state of the model that
* will be mixed in to the cache key.
* @return This request builder.
* @see com.bumptech.glide.signature.ObjectKey
*/
设置一些额外的数据混合到内存和磁盘缓存键中,允许调用者在缓存数据失效时有更多的控制。
注:该签名不会替换缓存密钥,它纯粹是添加的。
参数:
signature -一个唯一的非空Key,表示模型的当前状态,该状态将被混合到缓存密钥中。
返回:
这个请求构建器。
@NonNull
@CheckResult
public T signature(@NonNull Key signature) {
if (isAutoCloneEnabled) {
return clone().signature(signature);
}
this.signature = Preconditions.checkNotNull(signature);
fields |= SIGNATURE;
return selfOrThrowIfLocked();
}
/**
* Returns a copy of this request builder with all of the options put so far on this builder.
*
* <p>This method returns a "deep" copy in that all non-immutable arguments are copied such that
* changes to one builder will not affect the other builder. However, in addition to immutable
* arguments, the current model is not copied copied so changes to the model will affect both
* builders.
*
* <p>Even if this object was locked, the cloned object returned from this method will not be
* locked.
*/
@SuppressWarnings({
"unchecked",
// we don't want to throw to be user friendly
"PMD.CloneThrowsCloneNotSupportedException",
// The types we're using here do this automatically.
"PMD.CloneMethodReturnTypeMustMatchClassName"
})
返回此请求构建器的副本,其中包含到目前为止放置在此构建器上的所有选项。
此方法返回一个“deep”副本,因为所有非不可变参数都被复制,这样对一个构建器的更改不会影响到另一个构建器。但是,除了不可变的参数外,当前的模型不会被复制,因此对模型的更改将影响两个构建器。
即使这个对象被锁定,从这个方法返回的克隆对象也不会被锁定。
@CheckResult
@Override
public T clone() {
try {
BaseRequestOptions<?> result = (BaseRequestOptions<?>) super.clone();
result.options = new Options();
result.options.putAll(options);
result.transformations = new CachedHashCodeArrayMap<>();
result.transformations.putAll(transformations);
result.isLocked = false;
result.isAutoCloneEnabled = false;
return (T) result;
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
@NonNull
@CheckResult
public <Y> T set(@NonNull Option<Y> option, @NonNull Y value) {
if (isAutoCloneEnabled) {
return clone().set(option, value);
}
Preconditions.checkNotNull(option);
Preconditions.checkNotNull(value);
options.set(option, value);
return selfOrThrowIfLocked();
}
@NonNull
@CheckResult
public T decode(@NonNull Class<?> resourceClass) {
if (isAutoCloneEnabled) {
return clone().decode(resourceClass);
}
/**
* Sets the value for key {@link
* com.bumptech.glide.load.resource.bitmap.BitmapEncoder#COMPRESSION_FORMAT}.
*/
设置BitmapEncoder.COMPRESSION_FORMAT键的值。
@NonNull
@CheckResult
public T encodeFormat(@NonNull Bitmap.CompressFormat format) {
return set(BitmapEncoder.COMPRESSION_FORMAT, Preconditions.checkNotNull(format));
}
/** Sets the value for key {@link BitmapEncoder#COMPRESSION_QUALITY}. */
设置BitmapEncoder.COMPRESSION_QUALITY键的值。
@NonNull
@CheckResult
public T encodeQuality(@IntRange(from = 0, to = 100) int quality) {
return set(BitmapEncoder.COMPRESSION_QUALITY, quality);
}
/**
* Sets the time position of the frame to extract from a video.
*
* <p>This is a component option specific to {@link VideoDecoder}. If the default video decoder is
* replaced or skipped because of your configuration, this option may be ignored.
*
* @see VideoDecoder#TARGET_FRAME
* @param frameTimeMicros The time position in microseconds of the desired frame. If negative, the
* Android framework implementation return a representative frame.
*/
设置要从视频中提取的帧的时间位置。
这是VideoDecoder特有的组件选项。如果默认的视频解码器因您的配置而被替换或跳过,则此选项可能被忽略。
参数:
frameTimeMicros -所需帧的时间位置(以微秒为单位)。如果为负值,Android框架实现返回一个代表框架。
@NonNull
@CheckResult
public T frame(@IntRange(from = 0) long frameTimeMicros) {
return set(VideoDecoder.TARGET_FRAME, frameTimeMicros);
}
/**
* Sets the {@link DecodeFormat} to use when decoding {@link Bitmap} objects using {@link
* Downsampler} and Glide's default GIF decoders.
*
* <p>{@link DecodeFormat} is a request, not a requirement. It's possible the resource will be
* decoded using a decoder that cannot control the format ({@link
* android.media.MediaMetadataRetriever} for example), or that the decoder may choose to ignore
* the requested format if it can't display the image (i.e. RGB_565 is requested, but the image
* has alpha).
*
* <p>This is a component option specific to {@link Downsampler} and Glide's GIF decoders. If the
* default Bitmap decoders are replaced or skipped because of your configuration, this option may
* be ignored.
*
* <p>To set only the format used when decoding {@link Bitmap}s, use {@link #set(Option, Object)}}
* and {@link Downsampler#DECODE_FORMAT}. To set only the format used when decoding GIF frames,
* use {@link #set(Option, Object)} and {@link GifOptions#DECODE_FORMAT}.
*
* @see Downsampler#DECODE_FORMAT
* @see GifOptions#DECODE_FORMAT
*/
设置使用Downsampler和Glide默认的GIF解码器解码位图对象时使用的DecodeFormat。
DecodeFormat是请求,而不是要求。可能资源将使用无法控制格式的解码器进行解码(例如MediaMetadataRetriever),或者解码器可能会选择忽略请求的格式,如果它不能显示图像(即请求了RGB_565,但图像有alpha)。
这是一个组件选项特定于Downsampler和Glide的GIF解码器。如果由于您的配置而替换或跳过默认位图解码器,则此选项可能被忽略。
使用set(Option, Object)}和Downsampler.DECODE_FORMAT只设置解码bitmap时使用的格式。要只设置解码GIF帧时使用的格式,请使用set(Option, Object)和GifOptions.DECODE_FORMAT。
@NonNull
@CheckResult
public T format(@NonNull DecodeFormat format) {
Preconditions.checkNotNull(format);
return set(Downsampler.DECODE_FORMAT, format).set(GifOptions.DECODE_FORMAT, format);
}
/**
* Disables the use of {@link android.graphics.Bitmap.Config#HARDWARE} in {@link Downsampler} to
* avoid errors caused by inspecting Bitmap pixels, drawing with hardware support disabled,
* drawing to {@link android.graphics.Canvas}s backed by {@link Bitmap}s etc.
*
* <p>It's almost never safe to set {@link Downsampler#ALLOW_HARDWARE_CONFIG} to {@code true} so
* we only provide a way to disable hardware configs entirely. If no option is set for {@link
* Downsampler#ALLOW_HARDWARE_CONFIG}, Glide will set the value per request based on whether or
* not a {@link Transformation} is applied and if one is, the type of {@link Transformation}
* applied. Built in transformations like {@link FitCenter} and {@link
* com.bumptech.glide.load.resource.bitmap.DownsampleStrategy.CenterOutside} can safely use {@link
* android.graphics.Bitmap.Config#HARDWARE} because they can be entirely replaced by scaling
* within {@link Downsampler}. {@link Transformation}s like {@link #circleCrop()} that can't be
* replicated by {@link Downsampler} cannot use {@link Bitmap.Config#HARDWARE} because {@link
* android.graphics.Bitmap.Config#HARDWARE} cannot be drawn to {@link android.graphics.Canvas}s,
* which is required by most {@link Transformation}s.
*/
在Downsampler中禁用Bitmap. config . hardware的使用,以避免由于检查位图像素、禁用硬件支持绘图、支持位图绘制到画布等导致的错误。
设置Downsampler几乎是不安全的。ALLOW_HARDWARE_CONFIG设置为true,所以我们只提供了一种完全禁用硬件配置的方法。如果没有设置下采样器选项。ALLOW_HARDWARE_CONFIG, Glide将根据是否应用转换以及如果应用转换的类型来设置每个请求的值。内置的转换,如FitCenter和DownsampleStrategy。CenterOutside可以安全地使用Bitmap.Config.HARDWARE,因为它们可以完全被Downsampler中的缩放所取代。像circleCrop()这样的转换不能被Downsampler复制,不能使用位图。因为Bitmap.Config.HARDWARE不能被绘制到Canvass,这是大多数转换所需要的。
@NonNull
@CheckResult
public T disallowHardwareConfig() {
return set(Downsampler.ALLOW_HARDWARE_CONFIG, false);
}
/**
* Sets the {@link DownsampleStrategy} to use when decoding {@link Bitmap Bitmaps} using {@link
* Downsampler}.
*
* <p>This is a component option specific to {@link Downsampler}. If the defautlt Bitmap decoder
* is replaced or skipped because of your configuration, this option may be ignored.
*/
设置使用Downsampler解码位图时使用的DownsampleStrategy。
这是Downsampler特有的组件选项。如果默认位图解码器因您的配置而被替换或跳过,则此选项可能被忽略。
@NonNull
@CheckResult
public T downsample(@NonNull DownsampleStrategy strategy) {
return set(DownsampleStrategy.OPTION, Preconditions.checkNotNull(strategy));
}
/**
* Sets the read and write timeout for the http requests used to load the image.
*
* <p>This is a component option specific to Glide's default networking library and {@link
* com.bumptech.glide.load.model.stream.HttpGlideUrlLoader}. If you use any other networking
* library including Glide's Volley or OkHttp integration libraries, this option will be ignored.
*
* @see com.bumptech.glide.load.model.stream.HttpGlideUrlLoader#TIMEOUT
* @param timeoutMs The read and write timeout in milliseconds.
*/
设置用于加载图像的http请求的读写超时时间。
这是一个特定于Glide默认网络库和HttpGlideUrlLoader的组件选项。如果你使用任何其他网络库,包括Glide的Volley或OkHttp集成库,这个选项将被忽略。
参数:
timeoutMs -读写超时时间,单位为毫秒。
@NonNull
@CheckResult
public T timeout(@IntRange(from = 0) int timeoutMs) {
return set(HttpGlideUrlLoader.TIMEOUT, timeoutMs);
}
/**
* Applies {@link com.bumptech.glide.load.resource.bitmap.CenterCrop} to all default types, and
* ignores unknown types.
*
* <p>This will override previous calls to {@link #dontTransform()}.
*
* @see #optionalTransform(Class, Transformation)
* @see #centerCrop()
*/
对所有默认类型应用CenterCrop,忽略未知类型。
这将覆盖之前对dontTransform()的调用。
@NonNull
@CheckResult
public T optionalCenterCrop() {
return optionalTransform(DownsampleStrategy.CENTER_OUTSIDE, new CenterCrop());
}
/**
* Applies {@link CenterCrop} to all default types and throws an exception if asked to transform
* an unknown type.
*
* <p>this will override previous calls to {@link #dontTransform()} ()}.
*
* @see #transform(Class, Transformation)
* @see #optionalCenterCrop()
*/
将CenterCrop应用于所有默认类型,并在被要求转换未知类型时抛出异常。
这将覆盖之前对dontTransform()()}的调用。
@NonNull
@CheckResult
public T centerCrop() {
return transform(DownsampleStrategy.CENTER_OUTSIDE, new CenterCrop());
}
/**
* Applies {@link FitCenter} and to all default types, {@link DownsampleStrategy#FIT_CENTER} to
* image types, and ignores unknown types.
*
* <p>This will override previous calls to {@link #dontTransform()} and previous calls to {@link
* #downsample(DownsampleStrategy)}.
*
* @see #optionalTransform(Class, Transformation)
* @see #fitCenter()
*/
应用FitCenter和所有默认类型DownsampleStrategy。并忽略未知类型。
这将覆盖之前对dontTransform()和downsample(DownsampleStrategy)的调用。
@NonNull
@CheckResult
public T optionalFitCenter() {
return optionalScaleOnlyTransform(DownsampleStrategy.FIT_CENTER, new FitCenter());
}
/**
* Applies {@link FitCenter} and to all default types, {@link DownsampleStrategy#FIT_CENTER} to
* image types, and throws an exception if asked to transform an unknown type.
*
* <p>This will override previous calls to {@link #dontTransform()} and previous calls to {@link
* #downsample(DownsampleStrategy)}.
*
* @see #transform(Class, Transformation)
* @see #optionalFitCenter()
*/
应用FitCenter和所有默认类型DownsampleStrategy。FIT_CENTER转换为图像类型,如果要求转换未知类型则抛出异常。
这将覆盖之前对dontTransform()和downsample(DownsampleStrategy)的调用。
@NonNull
@CheckResult
public T fitCenter() {
return scaleOnlyTransform(DownsampleStrategy.FIT_CENTER, new FitCenter());
}
/**
* Applies {@link com.bumptech.glide.load.resource.bitmap.CenterInside} to all default types,
* {@link DownsampleStrategy#CENTER_INSIDE} to image types, and ignores unknown types.
*
* <p>This will override previous calls to {@link #dontTransform()} and previous calls to {@link
* #downsample(DownsampleStrategy)}.
*
* @see #optionalTransform(Class, Transformation)
* @see #centerInside()
*/
将CenterInside应用于所有默认类型DownsampleStrategy。设置为图像类型,忽略未知类型。
这将覆盖之前对dontTransform()和downsample(DownsampleStrategy)的调用。
@NonNull
@CheckResult
public T optionalCenterInside() {
return optionalScaleOnlyTransform(DownsampleStrategy.CENTER_INSIDE, new CenterInside());
}
/**
* Applies {@link CenterInside} to all default types, {@link DownsampleStrategy#CENTER_INSIDE} to
* image types and throws an exception if asked to transform an unknown type.
*
* <p>This will override previous calls to {@link #dontTransform()} and previous calls to {@link
* #downsample(DownsampleStrategy)}.
*
* @see #transform(Class, Transformation)
* @see #optionalCenterInside()
*/
将CenterInside应用于所有默认类型DownsampleStrategy。如果被要求转换未知类型,则抛出异常。
这将覆盖之前对dontTransform()和downsample(DownsampleStrategy)的调用。
@NonNull
@CheckResult
public T centerInside() {
return scaleOnlyTransform(DownsampleStrategy.CENTER_INSIDE, new CenterInside());
}
/**
* Applies {@link CircleCrop} to all default types, and ignores unknown types.
*
* <p>This will override previous calls to {@link #dontTransform()}.
*
* @see #optionalTransform(Transformation)
* @see #circleCrop()
*/
对所有默认类型应用CircleCrop,忽略未知类型。
这将覆盖之前对dontTransform()的调用。
@NonNull
@CheckResult
public T optionalCircleCrop() {
return optionalTransform(DownsampleStrategy.CENTER_OUTSIDE, new CircleCrop());
}
/**
* Applies {@link CircleCrop} to all default types and throws an exception if asked to transform
* an unknown type.
*
* <p>This will override previous calls to {@link #dontTransform()}.
*
* @see #transform(Class, Transformation)
* @see #optionalCenterCrop()
*/
将CircleCrop应用于所有默认类型,并在被要求转换未知类型时抛出异常。
这将覆盖之前对dontTransform()的调用。
@NonNull
@CheckResult
public T circleCrop() {
return transform(DownsampleStrategy.CENTER_INSIDE, new CircleCrop());
}
// calling optionalTransform() on the result of clone() requires greater access.
// calling downsample is guaranteed to modify the current object by the isAutoCloneEnabledCheck.
@SuppressWarnings({"WeakerAccess", "CheckResult"})
@NonNull
final T optionalTransform(
@NonNull DownsampleStrategy downsampleStrategy,
@NonNull Transformation<Bitmap> transformation) {
if (isAutoCloneEnabled) {
return clone().optionalTransform(downsampleStrategy, transformation);
}
downsample(downsampleStrategy);
return transform(transformation, /*isRequired=*/ false);
}
// calling transform() on the result of clone() requires greater access.
// calling downsample is guaranteed to modify the current object by the isAutoCloneEnabledCheck.
@SuppressWarnings({"WeakerAccess", "CheckResult"})
@NonNull
@CheckResult
final T transform(
@NonNull DownsampleStrategy downsampleStrategy,
@NonNull Transformation<Bitmap> transformation) {
if (isAutoCloneEnabled) {
return clone().transform(downsampleStrategy, transformation);
}
downsample(downsampleStrategy);
return transform(transformation);
}
@NonNull
private T scaleOnlyTransform(
@NonNull DownsampleStrategy strategy, @NonNull Transformation<Bitmap> transformation) {
return scaleOnlyTransform(strategy, transformation, true /*isTransformationRequired*/);
}
@NonNull
private T optionalScaleOnlyTransform(
@NonNull DownsampleStrategy strategy, @NonNull Transformation<Bitmap> transformation) {
return scaleOnlyTransform(strategy, transformation, false /*isTransformationRequired*/);
}
// We know that result will always be T since we created result.
@SuppressWarnings("unchecked")
@NonNull
private T scaleOnlyTransform(
@NonNull DownsampleStrategy strategy,
@NonNull Transformation<Bitmap> transformation,
boolean isTransformationRequired) {
BaseRequestOptions<T> result =
isTransformationRequired
? transform(strategy, transformation)
: optionalTransform(strategy, transformation);
result.isScaleOnlyOrNoTransform = true;
return (T) result;
}
/**
* Applies the given {@link Transformation} for {@link Bitmap Bitmaps} to the default types
* ({@link Bitmap}, {@link android.graphics.drawable.BitmapDrawable}, and {@link
* com.bumptech.glide.load.resource.gif.GifDrawable}) and throws an exception if asked to
* transform an unknown type.
*
* <p>This will override previous calls to {@link #dontTransform()}.
*
* @param transformation Any {@link Transformation} for {@link Bitmap}s.
* @see #optionalTransform(Transformation)
* @see #optionalTransform(Class, Transformation)
*/
// Guaranteed to modify the current object by the isAutoCloneEnabledCheck.
将给定的Bitmap转换应用到默认类型(Bitmap, BitmapDrawable和GifDrawable),并在被要求转换未知类型时抛出异常。
这将覆盖之前对dontTransform()的调用。
参数:
转换-位图的任何转换。
@SuppressWarnings("CheckResult")
@NonNull
@CheckResult
public T transform(@NonNull Transformation<Bitmap> transformation) {
return transform(transformation, /*isRequired=*/ true);
}
/**
* Applies the given {@link Transformation}s in the given order for {@link Bitmap Bitmaps} to the
* default types ({@link Bitmap}, {@link android.graphics.drawable.BitmapDrawable}, and {@link
* com.bumptech.glide.load.resource.gif.GifDrawable}) and throws an exception if asked to
* transform an unknown type.
*
* <p>This will override previous calls to {@link #dontTransform()}.
*
* @param transformations One or more {@link Transformation}s for {@link Bitmap}s.
* @see #optionalTransform(Transformation)
* @see #optionalTransform(Class, Transformation)
*/
将Bitmap的给定顺序中的给定转换应用到默认类型(Bitmap, BitmapDrawable和GifDrawable),并在被要求转换未知类型时抛出异常。
这将覆盖之前对dontTransform()的调用。
参数:
一个或多个位图转换。
// Guaranteed to modify the current object by the isAutoCloneEnabledCheck.
@SuppressWarnings({"unchecked", "varargs", "CheckResult"})
@NonNull
@CheckResult
public T transform(@NonNull Transformation<Bitmap>... transformations) {
if (transformations.length > 1) {
return transform(new MultiTransformation<>(transformations), /*isRequired=*/ true);
} else if (transformations.length == 1) {
return transform(transformations[0]);
} else {
return selfOrThrowIfLocked();
}
}
/**
* Applies the given {@link Transformation}s in the given order for {@link Bitmap Bitmaps} to the
* default types ({@link Bitmap}, {@link android.graphics.drawable.BitmapDrawable}, and {@link
* com.bumptech.glide.load.resource.gif.GifDrawable}) and throws an exception if asked to
* transform an unknown type.
*
* <p>This will override previous calls to {@link #dontTransform()}.
*
* @deprecated Deprecated due to api update, use {@link #transform(Transformation[])} instead
* @param transformations One or more {@link Transformation}s for {@link Bitmap}s.
* @see #optionalTransform(Transformation)
* @see #optionalTransform(Class, Transformation)
*/
将Bitmap的给定顺序中的给定转换应用到默认类型(Bitmap, BitmapDrawable和GifDrawable),并在被要求转换未知类型时抛出异常。
这将覆盖之前对dontTransform()的调用。
参数:
一个或多个位图转换
// Guaranteed to modify the current object by the isAutoCloneEnabledCheck.
@SuppressWarnings({"unchecked", "varargs", "CheckResult"})
@NonNull
@CheckResult
@Deprecated
public T transforms(@NonNull Transformation<Bitmap>... transformations) {
return transform(new MultiTransformation<>(transformations), /*isRequired=*/ true);
}
/**
* Applies the given {@link Transformation} for {@link Bitmap Bitmaps} to the default types
* ({@link Bitmap}, {@link android.graphics.drawable.BitmapDrawable}, and {@link
* com.bumptech.glide.load.resource.gif.GifDrawable}) and ignores unknown types.
*
* <p>This will override previous calls to {@link #dontTransform()}.
*
* @param transformation Any {@link Transformation} for {@link Bitmap}s.
* @see #transform(Transformation)
* @see #transform(Class, Transformation)
*/
将给定的转换应用到默认类型(Bitmap, BitmapDrawable和GifDrawable),忽略未知类型。
这将覆盖之前对dontTransform()的调用。
参数:
转换-位图的任何转换。
// Guaranteed to modify the current object by the isAutoCloneEnabledCheck.
@SuppressWarnings("CheckResult")
@NonNull
@CheckResult
public T optionalTransform(@NonNull Transformation<Bitmap> transformation) {
return transform(transformation, /*isRequired=*/ false);
}
@NonNull
T transform(@NonNull Transformation<Bitmap> transformation, boolean isRequired) {
if (isAutoCloneEnabled) {
return clone().transform(transformation, isRequired);
}
DrawableTransformation drawableTransformation =
new DrawableTransformation(transformation, isRequired);
transform(Bitmap.class, transformation, isRequired);
transform(Drawable.class, drawableTransformation, isRequired);
// TODO: remove BitmapDrawable decoder and this transformation.
// Registering as BitmapDrawable is simply an optimization to avoid some iteration and
// isAssignableFrom checks when obtaining the transformation later on. It can be removed without
// affecting the functionality.
transform(BitmapDrawable.class, drawableTransformation.asBitmapDrawable(), isRequired);
transform(GifDrawable.class, new GifDrawableTransformation(transformation), isRequired);
return selfOrThrowIfLocked();
}
/**
* Applies the given {@link Transformation} for any decoded resource of the given type and allows
* unknown resource types to be ignored.
*
* <p>Users can apply different transformations for each resource class. Applying a {@link
* Transformation} for a resource type that already has a {@link Transformation} will override the
* previous call.
*
* <p>If any calls are made to the non-optional transform methods, then attempting to transform an
* unknown resource class will throw an exception. To allow unknown types, users must always call
* the optional version of each method.
*
* <p>This will override previous calls to {@link #dontTransform()}.
*
* @param resourceClass The type of resource to transform.
* @param transformation The {@link Transformation} to apply.
*/
对给定类型的任何已解码资源应用给定的转换,并允许忽略未知资源类型。
用户可以为每个资源类应用不同的转换。为已经具有转换的资源类型应用转换将覆盖前面的调用。
如果对非可选转换方法进行了任何调用,那么试图转换未知资源类将引发异常。要允许未知类型,用户必须总是调用每个方法的可选版本。
这将覆盖之前对dontTransform()的调用。
参数:
resourceClass -要转换的资源的类型。
转换-要应用的转换。
@NonNull
@CheckResult
public <Y> T optionalTransform(
@NonNull Class<Y> resourceClass, @NonNull Transformation<Y> transformation) {
return transform(resourceClass, transformation, /*isRequired=*/ false);
}
@NonNull
<Y> T transform(
@NonNull Class<Y> resourceClass,
@NonNull Transformation<Y> transformation,
boolean isRequired) {
if (isAutoCloneEnabled) {
return clone().transform(resourceClass, transformation, isRequired);
}
Preconditions.checkNotNull(resourceClass);
Preconditions.checkNotNull(transformation);
transformations.put(resourceClass, transformation);
fields |= TRANSFORMATION;
isTransformationAllowed = true;
fields |= TRANSFORMATION_ALLOWED;
// Always set to false here. Known scale only transformations will call this method and then
// set isScaleOnlyOrNoTransform to true immediately after.
isScaleOnlyOrNoTransform = false;
if (isRequired) {
fields |= TRANSFORMATION_REQUIRED;
isTransformationRequired = true;
}
return selfOrThrowIfLocked();
}
/**
* Applies the given {@link Transformation} for any decoded resource of the given type and throws
* if asked to transform an unknown resource type.
*
* <p>This will override previous calls to {@link #dontTransform()}.
*
* @param resourceClass The type of resource to transform.
* @param transformation The {@link Transformation} to apply.
* @see #optionalTransform(Class, Transformation)
*/
对给定类型的任何已解码资源应用给定的转换,并在被要求转换未知资源类型时抛出。
这将覆盖之前对dontTransform()的调用。
参数:
resourceClass -要转换的资源的类型。
转换-要应用的转换。
// Guaranteed to modify the current object by the isAutoCloneEnabledCheck.
@SuppressWarnings("CheckResult")
@NonNull
@CheckResult
public <Y> T transform(
@NonNull Class<Y> resourceClass, @NonNull Transformation<Y> transformation) {
return transform(resourceClass, transformation, /*isRequired=*/ true);
}
/**
* Removes all applied {@link Transformation Transformations} for all resource classes and allows
* unknown resource types to be transformed without throwing an exception.
*/
移除所有资源类的所有应用转换,并允许在不引发异常的情况下转换未知资源类型。
@NonNull
@CheckResult
public T dontTransform() {
if (isAutoCloneEnabled) {
return clone().dontTransform();
}
transformations.clear();
fields &= ~TRANSFORMATION;
isTransformationRequired = false;
fields &= ~TRANSFORMATION_REQUIRED;
isTransformationAllowed = false;
fields |= TRANSFORMATION_ALLOWED;
isScaleOnlyOrNoTransform = true;
return selfOrThrowIfLocked();
}
/**
* Disables resource decoders that return animated resources so any resource returned will be
* static.
*
* <p>To disable transitions (fades etc) use {@link
* com.bumptech.glide.TransitionOptions#dontTransition()}
*/
禁用返回动画资源的资源解码器,这样返回的任何资源都将是静态的。
使用TransitionOptions.dontTransition()禁用过渡(淡出等等)
// Guaranteed to modify the current object by the isAutoCloneEnabledCheck.
@SuppressWarnings("CheckResult")
@NonNull
@CheckResult
public T dontAnimate() {
return set(GifOptions.DISABLE_ANIMATION, true);
}
/**
* Updates this options set with any options that are explicitly set in the given {@code T} object
* and returns this object if {@link #autoClone()} is disabled or a new {@code T} object if {@link
* #autoClone()} is enabled.
*
* <p>{@code #apply} only replaces those values that are explicitly set in the given {@code T}. If
* you need to completely reset all previously set options, create a new {@code T} object instead
* of using this method.
*
* <p>The options that will be set to values in the returned {@code T} object is the intersection
* of the set of options in this {@code T} object and the given {@code T} object that were
* explicitly set. If the values of any of the options conflict, the values in the returned {@code
* T} object will be set to those in the given {@code T} object.
*/
使用在给定T对象中显式设置的任何选项更新此选项集,并在autoClone()被禁用时返回此对象,或在autoClone()被启用时返回一个新的T对象。
#apply只替换那些在给定T中显式设置的值。如果你需要完全重置所有之前设置的选项,创建一个新的T对象而不是使用这个方法。
将被设置为返回的T对象中的值的选项是这个T对象中的选项集和显式设置的给定T对象中的选项集的交集。如果任何选项的值发生冲突,返回的T对象中的值将被设置为给定T对象中的值。
@NonNull
@CheckResult
public T apply(@NonNull BaseRequestOptions<?> o) {
if (isAutoCloneEnabled) {
return clone().apply(o);
}
BaseRequestOptions<?> other = o;
if (isSet(other.fields, SIZE_MULTIPLIER)) {
sizeMultiplier = other.sizeMultiplier;
}
if (isSet(other.fields, USE_UNLIMITED_SOURCE_GENERATORS_POOL)) {
useUnlimitedSourceGeneratorsPool = other.useUnlimitedSourceGeneratorsPool;
}
if (isSet(other.fields, USE_ANIMATION_POOL)) {
useAnimationPool = other.useAnimationPool;
}
if (isSet(other.fields, DISK_CACHE_STRATEGY)) {
diskCacheStrategy = other.diskCacheStrategy;
}
if (isSet(other.fields, PRIORITY)) {
priority = other.priority;
}
if (isSet(other.fields, ERROR_PLACEHOLDER)) {
errorPlaceholder = other.errorPlaceholder;
errorId = 0;
fields &= ~ERROR_ID;
}
if (isSet(other.fields, ERROR_ID)) {
errorId = other.errorId;
errorPlaceholder = null;
fields &= ~ERROR_PLACEHOLDER;
}
if (isSet(other.fields, PLACEHOLDER)) {
placeholderDrawable = other.placeholderDrawable;
placeholderId = 0;
fields &= ~PLACEHOLDER_ID;
}
if (isSet(other.fields, PLACEHOLDER_ID)) {
placeholderId = other.placeholderId;
placeholderDrawable = null;
fields &= ~PLACEHOLDER;
}
if (isSet(other.fields, IS_CACHEABLE)) {
isCacheable = other.isCacheable;
}
if (isSet(other.fields, OVERRIDE)) {
overrideWidth = other.overrideWidth;
overrideHeight = other.overrideHeight;
}
if (isSet(other.fields, SIGNATURE)) {
signature = other.signature;
}
if (isSet(other.fields, RESOURCE_CLASS)) {
resourceClass = other.resourceClass;
}
if (isSet(other.fields, FALLBACK)) {
fallbackDrawable = other.fallbackDrawable;
fallbackId = 0;
fields &= ~FALLBACK_ID;
}
if (isSet(other.fields, FALLBACK_ID)) {
fallbackId = other.fallbackId;
fallbackDrawable = null;
fields &= ~FALLBACK;
}
if (isSet(other.fields, THEME)) {
theme = other.theme;
}
if (isSet(other.fields, TRANSFORMATION_ALLOWED)) {
isTransformationAllowed = other.isTransformationAllowed;
}
if (isSet(other.fields, TRANSFORMATION_REQUIRED)) {
isTransformationRequired = other.isTransformationRequired;
}
if (isSet(other.fields, TRANSFORMATION)) {
transformations.putAll(other.transformations);
isScaleOnlyOrNoTransform = other.isScaleOnlyOrNoTransform;
}
if (isSet(other.fields, ONLY_RETRIEVE_FROM_CACHE)) {
onlyRetrieveFromCache = other.onlyRetrieveFromCache;
}
// Applying options with dontTransform() is expected to clear our transformations.
if (!isTransformationAllowed) {
transformations.clear();
fields &= ~TRANSFORMATION;
isTransformationRequired = false;
fields &= ~TRANSFORMATION_REQUIRED;
isScaleOnlyOrNoTransform = true;
}
fields |= other.fields;
options.putAll(other.options);
return selfOrThrowIfLocked();
}
/**
* Throws if any further mutations are attempted.
*
* <p>Once locked, the only way to unlock is to use {@link #clone()}
*/
如果尝试任何进一步的突变,则抛出。
一旦锁定,解锁的唯一方法是使用clone()
@NonNull
@SuppressWarnings("unchecked")
public T lock() {
isLocked = true;
// This is the only place we should not check locked.
return self();
}
/**
* Similar to {@link #lock()} except that mutations cause a {@link #clone()} operation to happen
* before the mutation resulting in all methods returning a new Object and leaving the original
* locked object unmodified.
*
* <p>Auto clone is not retained by cloned objects returned from mutations. The cloned objects are
* mutable and are not locked.
*/
与lock()类似,不同的是突变会导致clone()操作在所有返回新Object的方法之前发生,而原始锁定的对象不会被修改。
从突变返回的克隆对象不会保留自动克隆。克隆的对象是可变的,没有锁定。
@NonNull
public T autoClone() {
if (isLocked && !isAutoCloneEnabled) {
throw new IllegalStateException(
"You cannot auto lock an already locked options object" + ", try clone() first");
}
isAutoCloneEnabled = true;
return lock();
}
@NonNull
@SuppressWarnings("unchecked")
protected final T selfOrThrowIfLocked() {
if (isLocked) {
throw new IllegalStateException("You cannot modify locked T, consider clone()");
}
return self();
}
@SuppressWarnings("unchecked")
private T self() {
return (T) this;
}
总结
建造者模式是一种相对好用且较为容易阅读理解的。但是在建造者模式基础上添加工厂、原型等其他模式的影子。那在阅读上也会变得复杂和晦涩了。再结合编程语言的特性那复杂性再上一层。不过再复杂的变化也是从简单开始的。这两个建造者模式变化应用方式试着理解看懂即可。在应用开发上一般不会这么复杂。但是如果想提高阅读Android源码的速度,那建议多看几遍找找感觉!
本章作为建造者模式的补充阅读即可!
更多设计模式解读
单例模式
Glide设计模式之单例模式
空对象模式
Glide设计模式之空对象模式【EmptyModelLoader】【EmptyList<E>
建造者模式
Glide多种组合使用方式记录–没有全部亲测,大家可以根据实际需要选用
Glide设计模式之建造者(builder)模式1【GlideBuilder】
Glide设计模式之建造者(builder)模式2【RequestBuilder】
Glide设计模式之建造者(builder)模式3【RequestOptions】【BaseRequestOptions】
Glide设计模式之建造者(builder)模式4总结【MemorySizeCalculator】【GlideExecutor】【PreFillType】【LazyHeaders】
工厂模式
Glide设计模式之工厂模式1【ModelLoaderFactory】
Glide设计模式之工厂模式2【DiskCache.Factory】
Glide工厂模式3【TransitionFactory】【Transition】
Glide设计模式之工厂模式4总结
自研产品推荐
历时一年半多开发终于smartApi-v1.0.0版本在2023-09-15晚十点正式上线
smartApi是一款对标国外的postman的api调试开发工具,由于开发人力就作者一个所以人力有限,因此v1.0.0版本功能进行精简,大功能项有:
- api参数填写
- api请求响应数据展示
- PDF形式的分享文档
- Mock本地化解决方案
- api列表数据本地化处理
- 再加上UI方面的打磨
为了更好服务大家把之前的公众号和软件激活结合,如有疑问请大家反馈到公众号即可,下个版本30%以上的更新会来自公众号的反馈。
嗯!先解释不上服务端原因,API调试工具的绝大多数时候就是一个数据模型、数据处理、数据模型理解共识的问题解决工具,所以作者结合自己十多年开发使用的一些痛点来打造的,再加上服务端开发一般是面向企业的,作者目前没有精力和时间去打造企业服务。再加上没有资金投入所以服务端开发会滞后,至于什么时候会进行开发,这个要看募资情况和用户反馈综合考虑。虽然目前国内有些比较知名的api工具了,但作者使用后还是觉得和实际使用场景不符。如果有相关吐槽也可以在作者的公众号里反馈蛤!
下面是一段smartApi使用介绍: