工厂方法模式在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修饰的,也是为了让其他类继承的,这是典型的工厂模式的多工厂。