前言
原文:http://riversunny.top/2017/08/28/Android-mvp模式-rxjava-Retrofit/
最近自己整理了下Android的开发框架做为积累以方便后面的开发,特记录如下:
示例代码下载demo
整个框架采用已经应用的很广泛并得到了大家认可的mvp模式,mvp用present代替mvc中的C让V变得更纯粹有着良好的复用性。框架中还应用了rxjava响应式编程框架、butterknife注解框架、Retrofit网络库使得代码优雅而流畅。
mvp模式
相信大家对mvc模式已经并不陌生,mvc(Model-View-Controller),其中M指的是模型层、V指的是视图层、C指的是控制层,三者的关系如下:
在MVC模式中View层不仅通过Controller和model层打交道而且它还可以直接访问model,所以View里会包含Model信息,不可避免的还要包括一些业务逻辑导致要更改View也是比较困难的,至少那些业务逻辑是无法重用的,Controller并没有达到完全分离View和Model的目的
在MVP里,Presenter完全把Model和View进行了分离,主要的程序逻辑在Presenter里实现。而且,Presenter与具体的View是通过定义好的接口进行交互的,从而使得在变更View时候可以保持Presenter的不变,即重用!如图:
mvp的优点
1.模型与视图完全分离,我们可以修改视图而不影响模型;
2.可以更高效地使用模型,因为所有的交互都发生在一个地方——Presenter内部;
3.我们可以将一个Presenter用于多个视图,而不需要改变Presenter的逻辑。这个特性非常的有用,因为视图的变化总是比模型的变化频繁;
4.如果我们把逻辑放在Presenter中,那么我们就可以脱离用户接口来测试这些逻辑(单元测试)。
例子:
view层 包含两个基类MvpBaseActivity、MvpBaseFragment,如果你的view层由一个Activity多个Fragment组成为了防止Activity和present过于臃肿可以让每个Fragment继承MvpBaseFragment来和presenter绑定,然后view和present交互可以通过接口来定义。代码如下:
MvpBaseActivity:
public abstract class MvpBaseFragment extends Fragment {
private static final String TAG = "MvpBaseFragment";
//presenter对象
private T mPresenter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//创建presenter
mPresenter = createPresenter();
//view与presenter建立关联
mPresenter.attachView((V)this);
Log.i(TAG, "attachView-mPresenter="+mPresenter);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy()-mPresenter="+mPresenter);
mPresenter.detachView();
}
protected abstract T createPresenter();
}
例子中view层接口
public interface ITopicsView {
void setQuestData(String string);
void showLoading();
void hideLoading();
}
* Presenter层
包含MvpBasePresenter、接口Presenter,见代码:
MvpBasePresenter:
public abstract class MvpBasePresenterimplements Presenter{
//view接口类型的弱引用
protected Reference
//建立关联
public void attachView(V view){
mViewRef = new WeakReference
}
public void detachView(){
if(mViewRef!=null){
mViewRef.clear();
mViewRef =null;
}
}
protected V getView(){
return mViewRef.get();
}
public boolean isViewAttached(){
return mViewRef !=null && mViewRef.get() !=null;
}
/**
* 每次调用业务请求的时候都要先调用方法检查是否与View建立连接,没有则抛出异常
*/
public void checkViewAttached() {
if (!isViewAttached()) {
throw new top.riversunny.mvp_rxretrofit.mvp.MvpBasePresenter.MvpViewNotAttachedException();
}
}
public static class MvpViewNotAttachedException extends RuntimeException {
public MvpViewNotAttachedException() {
super("请求数据前请先调用 attachView(View) 方法与View建立连接");
}
}
}
Presenter:
public interface Presenter{
/**
* Presenter与View建立连接
*
* @param mvpView 与此Presenter相对应的View
*/
void attachView(V mvpView);
/**
* Presenter与View连接断开
*/
void detachView();
}
rxjava的使用可以阅读
http://gank.io/post/560e15be2dca930e00da1083
Retrofit的使用可以阅读
http://www.jianshu.com/p/308f3c54abdd
http://www.jianshu.com/p/94ca8a284ebb