Manager在项目中大多为单例模式且管理类之间会相互调用,因此统一的管理显得尤为重要。
public abstract class BaseManager {
public static final boolean DEBUG = BuildConfig.DEBUG;
/**
* 日志打印, logger.d("a = %d", 3);
*/
protected Logger logger = new Logger(this);
/**
* 管理器被初始化的回调,初始化整个管理器
*
* @param application
*/
public abstract void onManagerCreate(CDApplication application);
/**
* 所有管理器都初始化后执行
*/
public void onAllManagerCreated() {
}
/**
* 获得应用程序实例
*
* @return 应用实例
*/
public CDApplication getApplication() {
return CDApplication.getInstance();
}
/**
* 获得管理器
*
* @param manager 管理器类型
* @param <M> 管理器Class
* @return 管理器
*/
public <M extends BaseManager> M getManager(Class<M> manager) {
return CDApplication.getInstance().getManager(manager);
}
}
初始化:
private void initManager() {
List<BaseManager> managerList = new ArrayList<>();
registerManager(managerList);
for (BaseManager baseManager : managerList) {
injectManager(baseManager);
baseManager.onManagerCreate(this);
managers.put(baseManager.getClass().getName(), baseManager);
}
for (Map.Entry<String, BaseManager> entry : managers.entrySet()) {
entry.getValue().onAllManagerCreated();
}
}
实例化:
public void injectManager(Object object) {//注解object内的对象
Class<?> aClass = object.getClass();
while (aClass != BaseManager.class && aClass != Object.class) {//遍历全部
Field[] declaredFields = aClass.getDeclaredFields();//获取变量
if (declaredFields != null && declaredFields.length > 0) {
for (Field field : declaredFields) {
int modifiers = field.getModifiers();
if (Modifier.isFinal(modifiers) || Modifier.isStatic(modifiers)) {
// 忽略掉static 和 final 修饰的变量
continue;
}
if (!field.isAnnotationPresent(Manager.class)) {//是否为manager的注解
continue;
}
Class<?> type = field.getType();
if (!BaseManager.class.isAssignableFrom(type)) {//是否继承自manager
throw new RuntimeException("@Manager 注解只能应用到BaseManager的子类");
}
BaseManager baseManager = getManager((Class<? extends BaseManager>) type);
if (baseManager == null) {
throw new RuntimeException(type.getSimpleName() + " 管理类还未初始化!");
}
if (!field.isAccessible())//反射时先设置可访问属性再赋值
field.setAccessible(true);
try {
field.set(object, baseManager);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
aClass = aClass.getSuperclass();
}
}