Glide
一、什么是Glide?
Glide 是Android开源控件,是 Android 在开发中广泛使用的图片加载和缓存库。
二、为什么用Glide?
因为Glide简化 Android 应用中的图片加载过程,提供高效、流畅的用户体验。以下是 Android Glide 的一些主要特点和优势:
主要特点:
1.简单易用:
Glide 提供了直观且易于使用的 API,使得开发者能够快速地加载和显示图片,而无需担心复杂的图片处理逻辑。
例如:
1.1、不用Glide可能需要这样加载图片
// Kotlin 代码示例:不使用 Glide
// 假设你有一个 ImageView 和一个图片的 URL
val imageView: ImageView = findViewById(R.id.imageView)
val imageUrl: String = "http://example.com/image.jpg"
// 使用 AsyncTask 来异步加载图片
AsyncTask.execute(Runnable {
// 在后台线程中下载图片
val imageBitmap: Bitmap? = downloadImage(imageUrl)
// 将结果切换回 UI 线程
runOnUiThread {
// 在 UI 线程中设置 ImageView 的图片
imageView.setImageBitmap(imageBitmap)
}
})
// 模拟的图片下载函数,实际开发中应使用合适的网络库如 OkHttp, Retrofit 等
private fun downloadImage(url: String): Bitmap? {
// 实现图片下载和解码的逻辑
// 这里省略了实际的下载代码
return null // 返回下载并解码后的 Bitmap,或者为 null 表示下载失败
}
2、使用Glide加载图片
// Kotlin 代码示例:使用 Glide
// 假设你有一个 ImageView 和一个图片的 URL
val imageView: ImageView = findViewById(R.id.imageView)
val imageUrl: String = "http://example.com/image.jpg"
// 使用 Glide 加载图片
Glide.with(this)
.load(imageUrl)
.into(imageView)
// 无需关心下载、解码和缓存的细节,Glide 会自动处理
从上述两个例子中可以看出,相比之下,使用 Glide 大大简化了代码,仅仅三行则可以。你不需要担心线程管理、图片解码或缓存。
1.2、使用Glide加载图片
//使用 Glide
// 假设你有一个 ImageView 和一个图片的 URL
val imageView: ImageView = findViewById(R.id.imageView)
val imageUrl: String = "http://example.com/image.jpg"
// 使用 Glide 加载图片
Glide.with(this)
.load(imageUrl)
.into(imageView)
// 无需关心下载、解码和缓存的细节,Glide 会自动处理
从上述两个例子中可以看出,相比之下,使用 Glide 大大简化了代码,仅仅三行则可以加载出图片到View中。而且不需要担心线程管理、图片解码或缓存。
** ## 2.高效性能 :
以下我会从几方面解释Glide为什么高效
1 异步加载:
Glide 使用后台线程异步加载图片,从而避免阻塞 UI 线程。这确保了应用的流畅性和响应性,尤其是在加载大量图片或处理大图时。
2 缓存管理:
内置了强大的缓存机制,包括内存缓存和磁盘缓存。内存缓存可以快速提供之前加载过的图片,而磁盘缓存则可以在应用重新启动后或网络不可用时提供图片。
Glide 会根据图片的大小和访问频率智能地管理缓存,以减少重复加载和下载的开销。
3 图片解码与缩放:
Glide 也是使用Android原生代码进行图片解码,以最大限度地减少内存占用和计算开销。它会根据设备的屏幕密度和 ImageView 的尺寸智能地调整图片的大小和质量,避免加载过大或过小的图片。
4 生命周期管理:
Glide 紧密集成 Android 生命周期,可以感知 Activity 和 Fragment 的生命周期,自动暂停和恢复图片加载。这确保了图片加载与应用的生命周期保持一致,避免了不必要的资源消耗。
5 网络优化:
Glide 可以与流行的网络库(如 OkHttp)集成,利用这些库提供的连接池、重试机制等功能,进一步提高网络请求的性能。
3.生命周期管理:(正片来袭 Glide版本4.15.1)
Glide 能够感知到 Context(如 Activity 或 Fragment)的生命周期。这意味着当 Activity 或 Fragment 被暂停或销毁时,Glide 会相应地暂停或取消图片加载,从而避免了不必要的资源消耗。
首先是Glide的简单使用:
Glide.with(context)
.load("http://example.com/image.jpg")
.into(imageView);
这里使用的设计模式 : 建造者设计模式
下面我们根据源码来分析下:
1、with()获取RequestManager
@NonNull
public static RequestManager with(@NonNull Context context) {
return getRetriever(context).get(context);
}
//with还支持传入 Activity、FragmentActivity、Fragment、android.app.Fragment
//但是官方不建议activity,建议传入FragmentActivity或者androidx.appcompat.app.AppCompatActivity)
2、检测context的合法性,还有就是获取Glide。
@NonNull
private static RequestManagerRetriever getRetriever(@Nullable Context context) {
// Context could be null for other reasons (ie the user passes in null), but in practice it will
// only occur due to errors with the Fragment lifecycle.
Preconditions.checkNotNull(
context,
"You cannot start a load on a not yet attached View or a Fragment where getActivity() "
+ "returns null (which usually occurs when getActivity() is called before the Fragment "
+ "is attached or after the Fragment is destroyed).");
return Glide.get(context).getRequestManagerRetriever();
}
3、获取单例Glide
//通过双重检测机制获得一个单例Glide
public static Glide get(@NonNull Context context) {
if (glide == null) {
GeneratedAppGlideModule annotationGeneratedModule =
getAnnotationGeneratedGlideModules(context.getApplicationContext());
synchronized (Glide.class) {
if (glide == null) {
checkAndInitializeGlide(context, annotationGeneratedModule);
}
}
}
return glide;
}
3.1 检测和初始化Glide
static void checkAndInitializeGlide(
@NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
// In the thread running initGlide(), one or more classes may call Glide.get(context).
// Without this check, those calls could trigger infinite recursion.
if (isInitializing) {
throw new IllegalStateException(
"Glide has been called recursively, this is probably an internal library error!");
}
isInitializing = true;
try {
//初始化Glide
initializeGlide(context, generatedAppGlideModule);
} finally {
isInitializing = false;
}
}
3.2 初始化Glide
从下面代码,我们可以看到Glide从builder.build函数创建出来后,就放到一个全局静态变量上。
private static volatile Glide glide;
...
private static void initializeGlide(
@NonNull Context context,
@NonNull GlideBuilder builder,
@Nullable GeneratedAppGlideModule annotationGeneratedModule) <