MvpFrame架构设计策略
MvpFrame是一款是一款MVP通用框架,使用简单,有效的解决项目中的高度耦合性,使项目更有层次结构。
前序
随着项目的功能迭代,传统的MVC架构已经很难满足开发需求了,高耦合让维护成本变得越来越高,代码冗余程度也越来越高,代码最后变得臃肿不堪。所以,在实际项目中,我们跟多的选择MVP架构。MVP架构是代码结构层次更加清晰、项目更加容易维护,代码耦合性降低了。本文对于基础的mvp使用不做解释。
一、MvpFrame架构优点:
1)用泛型指定Presenter层,然后直接createPresenter方法即可获取到对于的presenter。
2)Presenter的生命周期与Activity生命周期同步绑定。
3)抽象工厂模式和反射机制,获取每个Presenter对象。
4)对Presenter的缓存处理。
5)异常情况下(如内存吃紧),对Presenter进行onSaveInstanceState保存数据的异常处理。
二、Presenter缓存策略:
1.存储过程:
1)用HashMap缓存Presenter。
2)将PresenterId缓存到bundle中,若内存中有新的bundle出现时(如横竖屏切换、内存吃紧强制退出app,保存了上次退出的bundle),都重新缓存PresenterId,onSaveInstanceState().注意:
每次bundle出现时,都需要重新缓存bundle,onRestoreInstanceState()
2.取出过程:
1)先将缓存在bundle中的PresenterId取出,然后通过PresenterId从WeakHashMap集合中取出Presenter
2)若内存中没有缓存bundle,然后PresenterFactory中回调获取Presenter
1、将PresenterId缓存到bundle中,若内存中有新的bundle出现时(如横竖屏切换、内存吃紧强制退出app,保存了上次退出的bundle),都重新缓存PresenterId
/**
* @deprecated 将PresenterId缓存到bundle中,若内存中有新的bundle出现时(如横竖屏切换、内存吃紧强制退出app,保存了上次退出的bundle),都重新缓存PresenterId
* @return
*/
public Bundle onSaveInstanceState() {
mBundle = new Bundle();
getPresenter();
if (mPresenter != null) {
String presenterId = PresenterStorage.INSTANCE.getPresenterId(mPresenter);
if (presenterId == null) { //若当前的Presenter未缓存到Map集合,则重新存入Map集合,然后重新将presenterId取出
PresenterStorage.INSTANCE.add(mPresenter);
presenterId = PresenterStorage.INSTANCE.getPresenterId(mPresenter);
}
mBundle.putString(PRESENTER_ID_KEY,presenterId);
}
return mBundle;
}
2、获取Presenter。先将缓存在bundle中的PresenterId取出,然后通过PresenterId从WeakHashMap集合中取出Presenter,若内存中没有缓存bundle,然后PresenterFactory中回调获取Presenter
public P getPresenter() {
if (mBundle != null) {
String presenterKey = mBundle.getString(PRESENTER_ID_KEY);
if (!TextUtils.isEmpty(presenterKey)) {
mPresenter = PresenterStorage.INSTANCE.getPresenter(presenterKey);
}
}
if (mPresenter == null && mPresenterFactory != null) { //程序走到这,说明Map集合中还未缓存Presenter,需要将Presenter缓存至map中
mPresenter = (P) mPresenterFactory.createPresenter();
PresenterStorage.INSTANCE.add(mPresenter);
}
return mPresenter;
}
用WeakHashMap集合缓存Presenter
/**
* @deprecated 获取presenter
* @param presenterId
* @param <P>
* @return
*/
public <P extends XPresenter> P getPresenter(String presenterId) {
AppUtil.checkNotNull(presenterId,"presenterId == null,getPresenter input id is not null!");
return !mIdFindPresenter.isEmpty() ? (P) mIdFindPresenter.get(presenterId) : null;
}
/**
* @deprecated 添加presenter
* @return
*/
public void add(final XPresenter presenter){
if (presenter != null) {
final String presenterId = PresenterStorage.class.getSimpleName() + "/" + System.nanoTime() + "/" + (int)(Math.random() * Integer.MAX_VALUE);
mIdFindPresenter.put(presenterId,presenter);
mPresenterFindId.put(presenter,presenterId);
LogUtil.showLog(PresenterStorage.class,"add...presenter" + mIdFindPresenter.size());
presenter.addDestoryListener(presenterId,new BasePresenter.OnDestoryListener() {
@Override
public void onDestory() {
String removeId = mPresenterFindId.remove(presenter);
mIdFindPresenter.remove(removeId);
LogUtil.showLog(PresenterStorage.class,"当前被删除的Presenter=" + presenter.toString() + ",PresenterId=" + removeId);
}
});
}
}
二、Presenter实例的获取:
使用抽象工厂获和反射获取每一个Presenter对象
1、定义获取对象的抽象接口
public interface PresenterFactory<P extends XPresenter> {
P createPresenter();
}
2、通过反射,获取PresenterFactory工厂对象
反射需要传入的对象即为具体的实现类的注解对象,@TargetPresenter(具体Presenter.class)
public static <P extends XPresenter> ReflectionPresenterFactory<P> fromViewClass(Class<?> clzzz){
ReflectionPresenterFactory factory = null;
try {
TargetPresenter annotation = clzzz.getAnnotation(TargetPresenter.class);
if (annotation == null) {
return null;
}else {
Class<? extends XPresenter> presenter = annotation.value();
if (presenter != null) {
factory = new ReflectionPresenterFactory(presenter);
}
}
}catch (Throwable t){
t.printStackTrace();
}
return factory;
}
3、创建Presenter
@Override
public P createPresenter() {
P pClass = null;
if (mPClass != null) {
try {
pClass = mPClass.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return pClass;
}