单例模式在很多开源框架和第三方服务中都有应用场景,本文只讨论最流行的框架。
Glide的Glide类
Glide框架的Glide类就是典型的单例模式:
public class Glide implements ComponentCallbacks2 {
// ……代码省略……
@GuardedBy("Glide.class")
private static volatile Glide glide;
/**
* Get the singleton.
*
* @return the singleton
*/
@NonNull
// Double checked locking is safe here.
@SuppressWarnings("GuardedBy")
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;
}
@GuardedBy("Glide.class")
@VisibleForTesting
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 {
initializeGlide(context, generatedAppGlideModule);
} finally {
isInitializing = false;
}
}
@VisibleForTesting
@Deprecated
public static synchronized void init(Glide glide) {
if (Glide.glide != null) {
tearDown();
}
Glide.glide = glide;
}
@VisibleForTesting
public static void init(@NonNull Context context, @NonNull GlideBuilder builder) {
GeneratedAppGlideModule annotationGeneratedModule = getAnnotationGeneratedGlideModules(context);
synchronized (Glide.class) {
if (Glide.glide != null) {
tearDown();
}
initializeGlide(context, builder, annotationGeneratedModule);
}
}
@VisibleForTesting
public static synchronized boolean isInitialized() {
return glide != null;
}
@GuardedBy("Glide.class")
private static void initializeGlide(
@NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
initializeGlide(context, new GlideBuilder(), generatedAppGlideModule);
}
@GuardedBy("Glide.class")
@SuppressWarnings("deprecation")
private static void initializeGlide(
@NonNull Context context,
@NonNull GlideBuilder builder,
@Nullable GeneratedAppGlideModule annotationGeneratedModule) {
// ……代码省略……
Glide glide = builder.build(applicationContext, manifestModules, annotationGeneratedModule);
applicationContext.registerComponentCallbacks(glide);
Glide.glide = glide;
}
@SuppressWarnings("PMD.UnusedFormalParameter")
Glide(
@NonNull Context context,
@NonNull Engine engine,
@NonNull MemoryCache memoryCache,
@NonNull BitmapPool bitmapPool,
@NonNull ArrayPool arrayPool,
@NonNull RequestManagerRetriever requestManagerRetriever,
@NonNull ConnectivityMonitorFactory connectivityMonitorFactory,
int logLevel,
@NonNull RequestOptionsFactory defaultRequestOptionsFactory,
@NonNull Map<Class<?>, TransitionOptions<?, ?>> defaultTransitionOptions,
@NonNull List<RequestListener<Object>> defaultRequestListeners,
@NonNull List<GlideModule> manifestModules,
@Nullable AppGlideModule annotationGeneratedModule,
@NonNull GlideExperiments experiments) {
// ……代码省略……
}
// ……代码省略……
}
从代码中可以看出,Glide类的构造方法是default的,意味着不能在外部实例化,然后get()方法是典型的DCL式单例。
除了以上提到的框架源码外,Picasso和EventBus等不再流行的框架,也包含了单例模式,本文不做过多讨论。