Glide源码阅读之建造者(builder)模式4总结【MemorySizeCalculator】【GlideExecutor】【PreFillType】【LazyHeaders】
Glide多种组合使用方式记录–没有全部亲测,大家可以根据实际需要选用
Glide设计模式之建造者(builder)模式1【GlideBuilder】
Glide设计模式之建造者(builder)模式2【RequestBuilder】
Glide设计模式之建造者(builder)模式3【RequestOptions】【BaseRequestOptions】
Glide设计模式之建造者(builder)模式4总结【MemorySizeCalculator】【GlideExecutor】【PreFillType】【LazyHeaders】
建造者(builder)模式在Glide里使用较多,把构建过程和表示分离,不同的参数可以构建不同的对象。甚至可以添加多个构建过程,比如:buildDefault、buildMaxxxx,buildMinxxx等等这样的构建表达。
在SDK第三方集成组件等场景下使用较多,SDK一般要配置APPID,secretKey,日志是否开启(一般和BuildConfig.isDebug绑定)等一系列的环境参数配置。
Android中也大量使用了builder模式,读懂Glide这几个Builder模式案例也就能很流畅阅读Android源码中的builder模式了。
汇总一下GlideBuilder、RequestBuilder这两者结合使用产生了对使用者进行工具化使用的便捷性。其基本的使用方式和结构经过了快十年的广泛使用和考验。可以说是很好的验证了设计模式中的使用不变,内部结构随着使用场景复杂,使用者的复杂而延展扩展性和包容性。同时大量的优秀贡献者遵守共识的bug提交单元测试脚本。也验证了Glide的性能卓越性。
能同时在使用便捷性、扩展性、包容性、兼顾内存性能、CPU性能、UI交互丝滑度等多方面,多角度的满足移动设备各种硬件性能、屏幕尺寸。各种应用工程的使用。的确是很哇塞的开源组件。
和读者们一起加油解析更多Glide优秀设计进行拿来即用主义。
附录1
其他建造者(builder)模式在Glide的应用
MemorySizeCalculator.Builder
/**
* Constructs an {@link MemorySizeCalculator} with reasonable defaults that can be optionally
* overridden.
*/
// Public API.
@SuppressWarnings({"WeakerAccess", "unused"})
com.bumptech.glide.load.engine.cache.MemorySizeCalculator.Builder
用合理的默认值构造MemorySizeCalculator,这些默认值可以被选择性地重写。
public Builder(Context context) {
this.context = context;
activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
screenDimensions =
new DisplayMetricsScreenDimensions(context.getResources().getDisplayMetrics());
// On Android O+ Bitmaps are allocated natively, ART is much more efficient at managing
// garbage and we rely heavily on HARDWARE Bitmaps, making Bitmap re-use much less important.
// We prefer to preserve RAM on these devices and take the small performance hit of not
// re-using Bitmaps and textures when loading very small images or generating thumbnails.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && isLowMemoryDevice(activityManager)) {
bitmapPoolScreens = 0;
}
}
/**
* Sets the number of device screens worth of pixels the {@link
* com.bumptech.glide.load.engine.cache.MemoryCache} should be able to hold and returns this
* Builder.
*/
设置MemoryCache应该能够保存的设备屏幕的像素数,并返回此生成器。
public Builder setMemoryCacheScreens(float memoryCacheScreens) {
。。。
/**
* Sets the number of device screens worth of pixels the {@link
* com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool} should be able to hold and returns
* this Builder.
*/
设置BitmapPool应该能够容纳的设备屏幕的像素数,并返回此生成器
public Builder setBitmapPoolScreens(float bitmapPoolScreens) {
。。。
/**
* Sets the maximum percentage of the device's memory class for standard devices that can be
* taken up by Glide's {@link com.bumptech.glide.load.engine.cache.MemoryCache} and {@link
* com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool} put together, and returns this
* builder.
*/
设置标准设备的内存类中可被Glide的MemoryCache和BitmapPool占用的最大百分比,并返回此构建器。
public Builder setMaxSizeMultiplier(float maxSizeMultiplier) {
。。。
/**
* Sets the maximum percentage of the device's memory class for low ram devices that can be
* taken up by Glide's {@link com.bumptech.glide.load.engine.cache.MemoryCache} and {@link
* com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool} put together, and returns this
* builder.
*
* @see ActivityManager#isLowRamDevice()
*/
设置低ram设备的内存类中可被Glide的MemoryCache和BitmapPool占用的最大百分比,并返回此构建器。
public Builder setLowMemoryMaxSizeMultiplier(float lowMemoryMaxSizeMultiplier) {
。。。
/**
* Sets the size in bytes of the {@link com.bumptech.glide.load.engine.bitmap_recycle.ArrayPool}
* to use to store temporary arrays while decoding data and returns this builder.
*
* <p>This number will be halved on low memory devices that return {@code true} from {@link
* ActivityManager#isLowRamDevice()}.
*/
设置解码数据时用于存储临时数组的ArrayPool的大小(以字节为单位),并返回此构建器。
在ActivityManager.isLowRamDevice()返回true的低内存设备上,这个数字将减半。
public Builder setArrayPoolSize(int arrayPoolSizeBytes) {
。。。
GlideExecutor.Builder
/** A builder for {@link GlideExecutor}s. */
一个用于GlideExecutors的构建器。
com.bumptech.glide.load.engine.executor.GlideExecutor.Builder
/**
* Allows both core and non-core threads in the executor to be terminated if no tasks arrive for
* at least the given timeout milliseconds.
*
* <p>Use {@link #NO_THREAD_TIMEOUT} to remove a previously set timeout.
*/
如果在给定的超时毫秒内没有任务到达,允许执行程序中的核心和非核心线程都被终止。
使用NO_THREAD_TIMEOUT删除前面设置的超时。
public Builder setThreadTimeoutMillis(long threadTimeoutMillis) {
。。。
/** Sets the maximum number of threads to use. */
设置要使用的最大线程数。
public Builder setThreadCount(@IntRange(from = 1) int threadCount) 。。。
/**
* Sets the {@link UncaughtThrowableStrategy} to use for unexpected exceptions thrown by tasks
* on {@link GlideExecutor}s built by this {@code Builder}.
*/
设置GlideExecutor。unaughtthrowablestrategy,用于该Builder构建的GlideExecutors上的任务抛出的意外异常。
public Builder setUncaughtThrowableStrategy(@NonNull UncaughtThrowableStrategy strategy) {
。。。
/**
* Sets the prefix to use for each thread name created by any {@link GlideExecutor}s built by
* this {@code Builder}.
*/
设置由该生成器构建的任何GlideExecutors创建的每个线程名所使用的前缀
public Builder setName(String name) {
。。。
/** Builds a new {@link GlideExecutor} with any previously specified options. */
public GlideExecutor build() {
if (TextUtils.isEmpty(name)) {
throw new IllegalArgumentException(
"Name must be non-null and non-empty, but given: " + name);
}
ThreadPoolExecutor executor =
new ThreadPoolExecutor(
corePoolSize,
maximumPoolSize,
/*keepAliveTime=*/ threadTimeoutMillis,
TimeUnit.MILLISECONDS,
new PriorityBlockingQueue<Runnable>(),
new DefaultThreadFactory(
threadFactory, name, uncaughtThrowableStrategy, preventNetworkOperations));
if (threadTimeoutMillis != NO_THREAD_TIMEOUT) {
executor.allowCoreThreadTimeOut(true);
}
return new GlideExecutor(executor);
}
}
PreFillType.Builder
/** Builder for {@link PreFillType}. */
PreFillType建设者。
com.bumptech.glide.load.engine.prefill.PreFillType.Builder
/**
* Constructor for a builder that uses the given size as the width and height of the Bitmaps to
* prefill.
*
* @param size The width and height in pixels of the Bitmaps to prefill.
*/
使用给定大小作为要预填充的位图的宽度和高度的构建器的构造器。
public Builder(int size) {
。。。
/**
* Constructor for a builder that uses the given dimensions as the dimensions of the Bitmaps to
* prefill.
*
* @param width The width in pixels of the Bitmaps to prefill.
* @param height The height in pixels of the Bitmaps to prefill.
*/
public Builder(int width, int height) {
。。。
/**
* Sets the {@link android.graphics.Bitmap.Config} for the Bitmaps to pre-fill.
*
* @param config The config to use, or null to use Glide's default.
* @return This builder.
*/
public Builder setConfig(@Nullable Bitmap.Config config) {
。。。
/**
* Sets the weight to use to balance how many Bitmaps of this type are prefilled relative to the
* other requested types.
*
* @param weight An integer indicating how to balance pre-filling this size and configuration of
* {@link android.graphics.Bitmap} against any other sizes/configurations that may be being
* pre-filled.
* @return This builder.
*/
设置用于平衡预填充的这种类型位图与其他请求类型的数量的权重。
public Builder setWeight(int weight) {
。。。
/** Returns a new {@link PreFillType}. */
PreFillType build() {
return new PreFillType(width, height, config, weight);
}
LazyHeaders.Builder
/**
* Adds an {@link LazyHeaderFactory} that will be used to construct a value for the given key*
* lazily on a background thread.
*
* <p>This class is not thread safe.
*
* <p>This class may include default values for User-Agent and Accept-Encoding headers. These will
* be replaced by calls to either {@link #setHeader(String, LazyHeaderFactory)} or {@link
* #addHeader(String, String)}, even though {@link #addHeader(String, LazyHeaderFactory)} would
* usually append an additional value.
*/
这个类不是线程安全的。
该类可能包括User-Agent和Accept-Encoding头的默认值。这些将被替换为调用setHeader(String, LazyHeaderFactory)或addHeader(String, String),即使addHeader(String, LazyHeaderFactory)通常会附加一个额外的值。
com.bumptech.glide.load.model.LazyHeaders.Builder
/**
* Adds a value for the given header and returns this builder.
*
* <p>Use {@link #addHeader(String, LazyHeaderFactory)} if obtaining the value requires I/O
* (i.e. an OAuth token).
*
* @see #addHeader(String, LazyHeaderFactory)
*/
为给定头添加值并返回此构建器。
使用addHeader(String, LazyHeaderFactory),如果获取值需要I/O(即OAuth令符)。
public Builder addHeader(@NonNull String key, @NonNull String value) {
。。。
/**
* Adds an {@link LazyHeaderFactory} that will be used to construct a value for the given key
* lazily on a background thread.
*
* <p>Headers may have multiple values whose order is defined by the order in which this method
* is called.
*
* <p>This class does not prevent you from adding the same value to a given key multiple times
*/
添加一个LazyHeaderFactory,用于在后台线程上为给定的键构造一个延迟值。
头文件可以有多个值,这些值的顺序由调用该方法的顺序定义。
这个类不会阻止您向给定键添加相同的值多次
public Builder addHeader(@NonNull String key, @NonNull LazyHeaderFactory factory) {
。。。
/**
* Replaces all existing {@link LazyHeaderFactory LazyHeaderFactorys} for the given key with the
* given {@link LazyHeaderFactory}.
*
* <p>If the given value is {@code null}, the header at the given key will be removed.
*
* <p>Use {@link #setHeader(String, LazyHeaderFactory)} if obtaining the value requires I/O
* (i.e. an OAuth token).
*/
用给定的LazyHeaderFactory替换给定键的所有LazyHeaderFactorys。
如果给定的值为空,那么给定键处的头文件将被删除。
使用setHeader(String, LazyHeaderFactory),如果获取值需要I/O(即OAuth令符)。
@SuppressWarnings({"UnusedReturnValue", "WeakerAccess"}) // Public API
public Builder setHeader(@NonNull String key, @Nullable String value) {
。。。
/**
* Replaces all existing {@link LazyHeaderFactory LazyHeaderFactorys} for the given key with the
* given {@link LazyHeaderFactory}.
*
* <p>If the given value is {@code null}, the header at the given key will be removed.
*/
用给定的LazyHeaderFactory替换给定键的所有LazyHeaderFactorys。
如果给定的值为空,那么给定键处的头文件将被删除。
public Builder setHeader(@NonNull String key, @Nullable LazyHeaderFactory factory) {
。。。
/** Returns a new immutable {@link LazyHeaders} object. */
public LazyHeaders build() {
copyOnModify = true;
return new LazyHeaders(headers);
}
更多设计模式解读
单例模式
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使用介绍: