工厂方法模式在Android SDK源码中有广泛的应用,无论app层还是framework层,无论是Java实现的还是Kotlin实现的。
BitmapFactory
Bitmap的构造方法都没有被public修饰,开发者必须用BitmapFactory来生成Bitmap对象,BitmapFactory中用于生产Bitmap实例的工厂方法如下:
public class BitmapFactory {
// ……代码省略……
/**
* Decode a file path into a bitmap. If the specified file name is null,
* or cannot be decoded into a bitmap, the function returns null.
*/
public static Bitmap decodeFile(String pathName, Options opts) {
// ……代码省略……
return bm;
}
/**
* Synonym for opening the given resource and calling
*/
public static Bitmap decodeResource(Resources res, int id, Options opts) {
// ……代码省略……
return bm;
}
/**
* Decode an immutable bitmap from the specified byte array.
*/
public static Bitmap decodeByteArray(byte[] data, int offset, int length, Options opts) {
// ……代码省略……
return bm;
}
/**
* Decode an input stream into a bitmap. If the input stream is null, or
* cannot be used to decode a bitmap, the function returns null.
* The stream's position will be where ever it was after the encoded data
* was read.
*/
@Nullable
public static Bitmap decodeStream(@Nullable InputStream is, @Nullable Rect outPadding,
@Nullable Options opts) {
// ……代码省略……
return bm;
}
/**
* Decode a bitmap from the file descriptor. If the bitmap cannot be decoded
* return null. The position within the descriptor will not be changed when
* this returns, so the descriptor can be used again as-is.
*/
public static Bitmap decodeFileDescriptor(FileDescriptor fd, Rect outPadding, Options opts) {
// ……代码省略……
return bm;
}
// ……代码省略……
}
可见BitmapFactory生产Bitmap对象的方法都是用static修饰的静态方法,是典型的简单工厂。
AppComponentFactory
众所周知Application和四大组件都是不能直接new出来的,需要通知system-server之后才能在当前进程生成实例。AppComponentFactory用来生产Applicaiton和四大组件的工厂方法代码如下:
public class AppComponentFactory {
public @NonNull ClassLoader instantiateClassLoader(@NonNull ClassLoader cl,
@NonNull ApplicationInfo aInfo) {
return cl;
}
public @NonNull Application instantiateApplication(@NonNull ClassLoader cl,
@NonNull String className)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
return (Application) cl.loadClass(className).newInstance();
}
public @NonNull Activity instantiateActivity(@NonNull ClassLoader cl, @NonNull String className,
@Nullable Intent intent)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
return (Activity) cl.loadClass(className).newInstance();
}
public @NonNull BroadcastReceiver instantiateReceiver(@NonNull ClassLoader cl,
@NonNull String className, @Nullable Intent intent)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
return (BroadcastReceiver) cl.loadClass(className).newInstance();
}
public @NonNull Service instantiateService(@NonNull ClassLoader cl,
@NonNull String className, @Nullable Intent intent)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
return (Service) cl.loadClass(className).newInstance();
}
public @NonNull ContentProvider instantiateProvider(@NonNull ClassLoader cl,
@NonNull String className)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
return (ContentProvider) cl.loadClass(className).newInstance();
}
/**
* @hide
*/
public static final AppComponentFactory DEFAULT = new AppComponentFactory();
}
生成Application和四大组件实例都是靠工厂方法生成,注意最后一行的单例模式的懒汉式实现,AppComponentFactory同时利用了工厂方法模式和单例模式。
在Android源码中简单工厂的应用非常广泛,是否有多工厂的应用呢?答案是有的,就是Jetpack组件里的ViewModelProvider.Factory。
ViewModelProvider.Factory
众所周知ViewModel作为MVVM架构中的VM,是不能直接new出来的,必须是用ViewModelProvider生成,我们来看源码:
@MainThread
public open operator fun <T : ViewModel> get(modelClass: Class<T>): T {
val canonicalName = modelClass.canonicalName
?: throw IllegalArgumentException("Local and anonymous classes can not be ViewModels")
return get("$DEFAULT_KEY:$canonicalName", modelClass)
}
@MainThread
public open operator fun <T : ViewModel> get(key: String, modelClass: Class<T>): T {
val viewModel = store[key]
if (modelClass.isInstance(viewModel)) {
(factory as? OnRequeryFactory)?.onRequery(viewModel!!)
return viewModel as T
} else {
@Suppress("ControlFlowWithEmptyBody")
if (viewModel != null) {
// TODO: log a warning.
}
}
val extras = MutableCreationExtras(defaultCreationExtras)
extras[VIEW_MODEL_KEY] = key
// AGP has some desugaring issues associated with compileOnly dependencies so we need to
// fall back to the other create method to keep from crashing.
return try {
factory.create(modelClass, extras)
} catch (e: AbstractMethodError) {
factory.create(modelClass)
}.also { store.put(key, it) }
}
// 用接口实现的抽象工厂
public interface Factory {
public fun <T : ViewModel> create(modelClass: Class<T>): T {
throw UnsupportedOperationException(
"Factory.create(String) is unsupported. This Factory requires " +
"`CreationExtras` to be passed into `create` method."
)
}
// ……代码省略……
}
// 具体工厂之一
@Suppress("SingletonConstructor")
public open class NewInstanceFactory : Factory {
@Suppress("DocumentExceptions")
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return try {
modelClass.getDeclaredConstructor().newInstance()
} catch (e: NoSuchMethodException) {
throw RuntimeException("Cannot create an instance of $modelClass", e)
} catch (e: InstantiationException) {
throw RuntimeException("Cannot create an instance of $modelClass", e)
} catch (e: IllegalAccessException) {
throw RuntimeException("Cannot create an instance of $modelClass", e)
}
}
// ……代码省略……
}
// 具体工厂之二
public open class AndroidViewModelFactory
private constructor(
private val application: Application?,
// parameter to avoid clash between constructors with nullable and non-nullable
// Application
@Suppress("UNUSED_PARAMETER") unused: Int,
) : NewInstanceFactory() {
/**
* Constructs this factory.
*/
@Suppress("SingletonConstructor")
public constructor() : this(null, 0)
@Suppress("SingletonConstructor")
public constructor(application: Application) : this(application, 0)
@Suppress("DocumentExceptions")
override fun <T : ViewModel> create(modelClass: Class<T>, extras: CreationExtras): T {
return if (application != null) {
create(modelClass)
} else {
val application = extras[APPLICATION_KEY]
if (application != null) {
create(modelClass, application)
} else {
// For AndroidViewModels, CreationExtras must have an application set
if (AndroidViewModel::class.java.isAssignableFrom(modelClass)) {
throw IllegalArgumentException(
"CreationExtras must have an application by `APPLICATION_KEY`"
)
}
super.create(modelClass)
}
}
}
@Suppress("DocumentExceptions")
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return if (application == null) {
throw UnsupportedOperationException(
"AndroidViewModelFactory constructed " +
"with empty constructor works only with " +
"create(modelClass: Class<T>, extras: CreationExtras)."
)
} else {
create(modelClass, application)
}
}
// ……代码省略……
}
不直接new出ViewModel对象而用工厂方法生成的原因是如果ViewModelStore中存在对象,则返回该对象,不存在才new出新对象。除了ViewModelProvider.AndroidViewModelFactory之外,接口ViewModelProvider.Factory还有许多实现的子类,而且AndroidViewModelFactory也是用open修饰的,也是为了让其他类继承的,这是典型的工厂模式的多工厂。