Android MVP架构的使用
2016-01-06 13:57
701 查看
前言
在现实项目中,我们经常会遇到这样一种情况,就是一个Activity类不仅要处理几种业务逻辑,同时还要兼顾着数据的请求以及UI的操作,这样造成的后果就是整个类的代码会出现上千行,更有胜者是几千行。显而易见,这种处理方式是不妥的,不仅违反了面向对象中单一职责原则,而且对于整个项目来说,也不利于项目的扩展和维护。(单一职责原则:不要存在多于一个导致类变更的原因。通俗的说,即一个类只负责一项职责。)那么,面对这种情况,我们该如何去架构整个项目?由于android项目本身就是MVC架构的体现,Activity充当了Controller,所以我们需要一种新的架构去替代MVC。MVP初步了解
MVP:(Model-View-Presenter)它是从MVC模式演变而来的,它与MVC模式相同的地方是,Controller/Presenter负责逻辑的处理,Model提供数据,View负责展示。作为一种新的模式,MVP与MVC有着一个重大的区别,在MVP中View并不直接使用Model,它们之间的通信是通过Presenter来进行的,所有的交互都发生在Presenter内部,而在MVC中View会从Model中读取数据而不是通过Controller。MVC图示
MVP图示
使用MVP的优点:
模型与视图完全分离,我们可以修改视图而不影响模型可以更高效的使用模型,因为所有的交互都发生在一个地方,即Presendter内部
我们可以将一个Presenter用于多个视图,而不需要改变Presenter的逻辑。这个特性非常有用,因为视图的变化总是比模型的变化频繁。
如果我们把逻辑放在Presenter中,那么我们就可以脱离用户来测试这些逻辑(单元测试)
MVP在Android中使用
View层负责处理用户时间和视图部分的展示,在Android中,它可能是Activity或者Fragment类Model层负责访问数据。数据可以是远程Server API,本地数据库或者Share的Preference等
Presenter层是链接(或适配)View和Model的桥梁
示例
项目结构定义一接口INewsView,作为View层和Presenter层关联的纽带,View层去实现该接口,而Presenter通过INewsView进行改变Activity的UI,同时Presenter类也和Model层进行关联操作
INewsView接口
public interface INewsView { void initView();//初始化控件 void startLoad();//开始请求数据 void loadSuccess(List<NewsBean> newsBeanList);//请求成功,数据不为空 void loadFail();//请求失败 void loadEmpty();//请求成功,数据为空 }
Activity类去实现该接口,进行UI逻辑操作
public class MainActivity extends AppCompatActivity implements INewsView{ private NewsPersenter newsPersenter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); newsPersenter = new NewsPersenter(this); newsPersenter.requestData(); } @Override public void initView() { //初始化控件 } @Override public void startLoad() { //请求数据前UI操作 } @Override public void loadSuccess(List<NewsBean> newsBeanList) { //请求成功,数据不为空,UI操作 } @Override public void loadFail() { //请求失败,UI操作 } @Override public void loadEmpty() { //请求成功,数据为空,UI操作 } }
NewsPresenter类
public class NewsPersenter { private INewsView iNewsView; public NewsPersenter(INewsView iNewsView) { this.iNewsView = iNewsView; this.iNewsView.initView(); } public void requestData() { //请求数据前数据前UI操作 iNewsView.startLoad(); //请求数据,异步请求 NewsHttpRequest.requestNewsList(new Callback<List<NewsBean>>() { @Override public void onResponse(Response<List<NewsBean>> response) { if (response == null || response.body() == null || response.body().isEmpty()) { //请求成功,无数据 iNewsView.loadEmpty(); } else { //请求成功,有数据 iNewsView.loadSuccess(response.body()); } } @Override public void onFailure(Throwable t) { //请求失败 iNewsView.loadFail(); } }); } }
NewsHttpRequest类,进行数据请求,Model层操作
public class NewsHttpRequest { public static interface INewsRequest { @GET("/NewsService/newsList") Call<List<NewsBean>> getNewsBeanList(); } public static void requestNewsList(Callback<List<NewsBean>> callBack) { Retrofit retrofit = new Retrofit.Builder().baseUrl("http://localhost:8080") .addConverterFactory(GsonConverterFactory.create()) .build(); retrofit.create(INewsRequest.class).getNewsBeanList().enqueue(callBack); } }
ps:当项目比较小,业务逻辑不多的时候,不建议使用MVP模式
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories