简介
由于在Android项目开发中我们经常会用到图片加载,你会选择什么第三库来加载图片,今天让我们来学习一下Glide图片加载库的源码吧,之前文章有讲解到Glide的简单使用。
简单使用
这里就不说添加依赖那些了,大家可以看官方文档,或者我之前的文章Glide的简单使用,但是版本现在最新的版本是4.8.0
。
接下来我们看看Glide是如何加载图片的,如下代码
public class MainActivity extends AppCompatActivity {
ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = findViewById(R.id.imageView);
Glide.with(this).load("http://goo.gl/gEgYUd").into(imageView);
}
}
我们通过上述代码中得到,Glide加载的使用方式是非常简单的。好了根据这句代码我们进行Glide的源码分析吧。
Glide.with(this).load("http://goo.gl/gEgYUd").into(imageView);
通过上述代码我们知道Glide中的with(this)调用的方法中携带了Activity或者Fragment的上下文对象其作用是:用于绑定该上下文对象的生命周期,如Activity或者Fragment的声明周期。代码如下:共有6个不同参数构造方法,返回静态的RequestManager
,用于加载图片。
//contex对象
public static RequestManager with(@NonNull Context context) {
return getRetriever(context).get(context);
}
/**
* Begin a load with Glide that will be tied to the given {@link android.app.Activity}'s lifecycle
* and that uses the given {@link Activity}'s default options.
*
* @param activity The activity to use.
* @return A RequestManager for the given activity that can be used to start a load. 用于启动加载的给定activity上下文的RequestManager
*/
public static RequestManager with(@NonNull Activity activity) {
return getRetriever(activity).get(activity);
}
//FragmentActivity 上下文对象
public static RequestManager with(@NonNull FragmentActivity activity) {
return getRetriever(activity).get(activity);
}
// fragment上下文对象
public static RequestManager with(@NonNull Fragment fragment) {
return getRetriever(fragment.getActivity()).get(fragment);
}
//V4的fragment对象
public static RequestManager with(@NonNull android.app.Fragment fragment) {
return getRetriever(fragment.getActivity()).get(fragment);
}
// view对象
public static RequestManager with(@NonNull View view) {
return getRetriever(view.getContext()).get(view);
}
RequestManager
是通过RequestManagerRetriever
的get()
方法获取,而get() 方法中的参数就是我们上述代码传递过来的上下文对象。
然后getRetriever(Context context)
方法返回的对象是RequestManagerRetriever
,如下代码所示。
private static RequestManagerRetriever getRetriever(@Nullable Context context) {
// 这里通过方法checkNotNull() 校验携带的上下文是否为null,如果是null将抛出空指针异常
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();
}
如果校验上下文对象并无异常,则通过Glide.get(context).getRequestManagerRetriever();
返回 RequestManagerRetriever
对象。
//这里使用的是双重校验单例方式初始化Glide实例
public static Glide get(@NonNull Context context) {
if (glide == null) {
synchronized (Glide.class) {
if (glide == null) {
//检查并初始化Glide
checkAndInitializeGlide(context);
}
}
}
return glide;
}
在checkAndInitializeGlide(context)方法中的initializeGlide(context,builder)
方法进行初始化,实例化唯一的Glide实例(双重校验单例方式获取)。
private static void initializeGlide(@NonNull Context context, @NonNull GlideBuilder builder) {
Context applicationContext = context.getApplicationContext();//获取长连接上下文对象
GeneratedAppGlideModule annotationGeneratedModule = getAnnotationGeneratedGlideModules();//通过注解方式生成GeneratedAppGlideModule
List<com.bumptech.glide.module.GlideModule> manifestModules = Collections.emptyList();
if (annotationGeneratedModule == null || annotationGeneratedModule.isManifestParsingEnabled()) {
//加载Glide Module
manifestModules = new ManifestParser(applicationContext).parse();
}
if (annotationGeneratedModule != null
&& !annotationGeneratedModule.getExcludedModuleClasses().isEmpty()) {
Set<Class<?