初始化:Glide.java
Posted bdmh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了初始化:Glide.java相关的知识,希望对你有一定的参考价值。
这篇文章,我们从Glide.with来展开了解一下Glide的源码。
Glide.with有多个重载,with方法的参数有可能是Context、Activity、Fragment等。
请记住一点,Glide的context需要是Application级别的Context,不要在生命周期事件中开始和停止。
下面的方法可以在fragment 或 activity 生命周期之外使用 (比如 services,notification thumbnails).
public static RequestManager with(@NonNull Context context)
return getRetriever(context).get(context);
下面这个和给定的Activity的生命周期绑定并使用它默认的配置
public static RequestManager with(@NonNull Activity activity)
return getRetriever(activity).get(activity);
下面这个针对 androidx.fragment.app.FragmentActivity 类型的
public static RequestManager with(@NonNull FragmentActivity activity)
return getRetriever(activity).get(activity);
下面这个针对 androidx.fragment.app.Fragment 类型的
public static RequestManager with(@NonNull Fragment fragment)
return getRetriever(fragment.getContext()).get(fragment);
下面这个针对android.app.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);
我们在所有的with方法中,都看到了getRetriever这个函数。
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();
该方法,返回RequestManagerRetriever对象,RequestManagerRetriever是一个提供了一些静态方法,用来创建com.bumptech.glide.RequestManager实例,并可以在activity和fragment中检索对应的com.bumptech.glide.RequestManager对象。
在Glide内部有RequestManagerRetriever变量声明,并且在Glide初始化时,赋值。
private final RequestManagerRetriever requestManagerRetriever;
到现在,我们依然没有看到Glide是如何创建的,不创建,那怎么使用呢?马上来了,看这句话
Glide.get(context).getRequestManagerRetriever()
private static volatile Glide glide;
//双锁机制创建单例
public static Glide get(@NonNull Context context)
if (glide == null)
//这里会动态生成代码,我们可以自定义Module来配置Glide
GeneratedAppGlideModule annotationGeneratedModule =
getAnnotationGeneratedGlideModules(context.getApplicationContext());
synchronized (Glide.class)
if (glide == null)
//c创建
checkAndInitializeGlide(context, annotationGeneratedModule);
return glide;
在Glide内部,定义了一个私有的静态变量glide,看上面的代码就很清楚的看到,Glide内部使用的是单例模式。在get方法中,使用了检测双锁的机制,来创建单例。
GeneratedAppGlideModule 我们后面文章讲解。继续看代码。
private static void checkAndInitializeGlide(
@NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule)
// 在initGlide()线程中, Glide.get(context)会被多次调用
// 如果没有下面的判断, 会引起递归.
if (isInitializing)
throw new IllegalStateException(
"You cannot call Glide.get() in registerComponents(),"
+ " use the provided Glide instance instead");
isInitializing = true;
initializeGlide(context, generatedAppGlideModule);
isInitializing = false;
最终会调用下面的方法初始化Glide。我们暂时先略过和Module相关的代码。
private static void initializeGlide(
@NonNull Context context,
@NonNull GlideBuilder builder,
@Nullable GeneratedAppGlideModule annotationGeneratedModule)
......
//获取Application级别的Context
Context applicationContext = context.getApplicationContext();
//Build模式创建Glide实例
Glide glide = builder.build(applicationContext);
......
//赋值给单例对象
Glide.glide = glide;
builder.build方法中会调用Glide的初始化。《GlideBuilder》
Glide build(@NonNull Context context)
......
return new Glide(
//上下文-ApplicationContext
context,
//用来加载和管理活动和缓存中资源的
engine,
//MemoryCache接口,管理缓存中资源的
memoryCache,
//bitmap池子,用来复用图像的
bitmapPool,
//数组池子,管理各种数组对象
arrayPool,
//前面提到的 RequestManagerRetriever 实例
requestManagerRetriever,
//工厂类,负责产生ConnectivityMonitor对象
//ConnectivityMonitor是用来监控网络事件的
connectivityMonitorFactory,
//日志级别,默认Log.INFO
logLevel,
//提供各种options配置
defaultRequestOptionsFactory,
//资源加载完后的过度效果,比如bitmap的动画效果
//Map结构
defaultTransitionOptions,
//加载图像监听
defaultRequestListeners,
experiments);
Glide的构造方法中,代码非常多,大概就是下面几大块。
把上面的参数,赋值给内部变量
Glide(......)
this.engine = engine;
this.bitmapPool = bitmapPool;
this.arrayPool = arrayPool;
this.memoryCache = memoryCache;
this.requestManagerRetriever = requestManagerRetriever;
this.connectivityMonitorFactory = connectivityMonitorFactory;
this.defaultRequestOptionsFactory = defaultRequestOptionsFactory;
获取资源对象
final Resources resources = context.getResources();
注册组件。Glide有一个Registry类,专门负责管理组件的,比如Module、编码解码、过度效果等等。我们来看一个我们接触最多的组件。
Glide(......)
registry.append(GlideUrl.class, InputStream.class, new HttpGlideUrlLoader.Factory());
上面这个就是注册一个用来下载图像的网络组件HttpGlideUrlLoader。它内部使用的是HttpURLConnection组件进行网络请求的。这个是可以替换的,后面再讲。
最后,会初始化一个全局的GlideContext,给Glide中所有注册的内部以及对外组件访问资源用的。
Glide(......)
glideContext =
new GlideContext(
context,
arrayPool,
registry,
imageViewTargetFactory,
defaultRequestOptionsFactory,
defaultTransitionOptions,
defaultRequestListeners,
engine,
experiments,
logLevel);
);
到这,一个Glide单例对象,就被创建好了,我们就可以在项目中使用了。
以上是关于初始化:Glide.java的主要内容,如果未能解决你的问题,请参考以下文章