您的位置:首页 > 移动开发 > Android开发

Android学习笔记MVP模式框架

2016-08-23 21:56 363 查看

Android学习笔记MVP模式框架

1.MVP模式介绍:

在上一次学习中,我简单的介绍了MVC构架,这次我来简单的介绍下什么是MVP。对于MVP,他其实就是MVC的一个演化版本,MVP全称Model View Presenter。目前MVP在android应用开发中越来越重要了,相信不少的开发者也在各种讨论关于MVP的理论了。那么这个MVP模式他到底有哪些应用的好处呢?首先MVP能够有效的降低View的复杂性,避免业务逻辑被塞进View中,使得View代码优化了不少。MVP模式会解除View与Model的耦合,同时又带来了良好的可扩展性、可测试性,保证了系统的整洁性、灵活性。可能对于简单的应用,你会觉得MVP会稍微显得有点麻烦,因为他提出了各种各样的接口概念,是的整个应用充斥着零散的接口,但是对于比较复杂的应用来说,MVP模式是一种良好的构架模式,它能够非常好的组织应用结构,使得应用变得灵活

 

 

2. MVP简单结构图:



从上图可以看出,MVP模式很好的分离显示层和逻辑层,他们之间通过接口进行通信,降低耦合。理想化的MVP模式可以实现同一份逻辑代码搭配不同的显示界面,因为他们之间并不依赖于具体,而是依赖与抽象。这使得Presenter可以运用于任何实现了View逻辑接口的UI,使之具有更广泛的使用性,保证了灵活度。

 

3. MVP模式的三个角色:

3.1 Presenter——交互中间人

Presenter主要作为沟通View和Model的桥梁,它从Model层检索数据后,返回给View层,是的View
和Model直接没有耦合,也将业务逻辑从View角色上抽离出来,相比MVC模式,就很好的减少了View
中的逻辑实现代码。


 

3.2 View——用户界面

View通常是指Activity、Fragment或者某个View控件,它含有一个Presenter成员变量。通常View需要
实现一个逻辑接口,将View上的操作通过会转交给Presenter进行实现,最后,Presenter调用View逻辑
接口将结果返回给View元素。
 
 


3.3 Model——数据的存储

对于一个结构化的App来说,Model角色主要是提供数据的存取功能。Presenter需要通过Model层存
储、获取数据,Model就像一个数据仓库。更直白地说,Model是封装了数据库Dao或者网络获取数据的
角色,或者两种数据获取方式的集合。


 

4. MVP的代码实现:

关于具体的实现我就不在这里重复写了,有想了解的大家可以参考我的这些MVP模式框架的代码:

Android-缓存网络图片(MVP模式)学习笔记

Android之SqliteDatabase(MVP模式)实现用户登录注册功能

Android MVP模式 解析JSON 显示到ListView上

 

5. 关于MVP与Activity、Fragment的生命周期:

综合上面的代码,我们可以很清除的知道,MVP有很多有点,例如易于维护、易于测试、松耦合、复用性高、健壮稳定、易于扩展,但是,由于Presenter经常性地执行一些耗时操作,例如,我们上述的缓存网络请求网络图片。由于Presenter持有了MainActity的强引用,如果在请求结束之前Activity被销毁了,那么由于网络请求还没有返回,导致Presenter一直持有MainActivity对象,是的MainActivity对象无法被回收,此时就会发生内存泄露。那么对于这种问题如何解决呢?答案是可以通过弱引用和Activity、Fragment的生命周期来解决这个问题。首先建立一个Presenter抽象类,我们把它命名为BaseAdapter,他是一个泛型类,泛型类类型为View角色要实现的接口类型。具体代码如下。

BasePresenter.java

public class BasePresenter<V extends ViewInter> {

protected WeakReference<V> weakReference;//View接口类型的弱引用

public void attach(V t){
weakReference = new WeakReference<>(t);//每次将需要关联的View接口类型的类与其建立联系
}

public void deAttach(){//如果Activity、Fragment等View控件销毁时调用该方法,解除他们之间的关联
if(weakReference != null){
weakReference.clear();
weakReference = null;
}
}
public boolean isViewAttached(){
return weakReference != null && weakReference.get() != null;
}
public V getView(){
if(weakReference != null){
return weakReference.get();
}
return  null;
}


以上的四个方法,分别是建立关联、解除关联、判断是否与View建立了关联、获取View。View类型通过Presenter的泛型类型传递过来,Presenter对这个View持有弱引用。通常情况下这个View类型应该是实现了某个特定接口的Activity或者Fragment等类型。接下来还需要创建一个BaseActivity基类,通过这个基类的生命周期方法来控制它与Presenter的关系。相关代码如下。

BaseActivity.java

public abstract class BaseActivity<V extends ViewInter,T extends BasePresenter> extends AppCompatActivity {

protected T basePresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
basePresenter = getBasePresenter();
basePresenter.attach((V)this);
}

public abstract T getBasePresenter();

@Override
protected void onDestroy() {
basePresenter.deAttach();
super.onDestroy();
}
}


BaseActivity含有两个泛型参数,第一个是View接口类型,第二个是Presenter的具体类型。通过泛型参数,使得一些通用的逻辑可以被抽象到BaseActivity类中。下面看看具体要使用的MainActivity类的实现。

MainActivity.java

//主界面启动,展示数据等。
public class MainActivity extends BaseActivity<MainActivity,Presenter> implements ViewInter<Bean.NewslistBean> {

private String path = "http://apis.baidu.com/txapi/mvtp/meinv?num=10";
private GridView mGrid;
private MyAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
basePresenter.load(path);
}

private void init() {
mGrid = (GridView) findViewById(R.id.mGrid);
}

@Override
public Presenter getBasePresenter() {
return new Presenter();
}

private void showListData(List<Bean.NewslistBean> data) {
if (adapter == null) {
adapter = new MyAdapter(data, R.layout.list_item);
mGrid.setAdapter(adapter);
} else {

}
}
//通过presenter代理类为我们提供数据
@Override
public void getAdapterData(List<Bean.NewslistBean> data) {
showListData(data);
}
}


通过上面的代码,大家可以看出,在BaseActivity中的onCreate方法中,会通过getBasePresenter方法创建一个具体的Presenter,这个Presenter的类型就是BasePresenter类型。构建Presenter之后调用attach方法与Activity建立关联。而在onDestory方法中,则会与Activity解除关联,从而避免内存泄露。有些人可能会问,如果在onDestory中解除了对Activity的引用,那么就没有必要再用弱引用了。对于这个问题的答案是,并不是在任何情况下Activity的onDestroy都会被调用,一旦这种情况发生,弱引用也能够保证不会造成内存泄露。而通过BaseActivity的封装维护Presenter与View关联关系的代码,使得子类可以避免重复的代码,上面的代码正是如此。Presenter的创建以及View建立关联等操作都被封装到BaseActivity中,消除了子类重复代码的同时又避免了Activity的内存泄露问题。所以,在以后的设计中,你都可以为Activity、Fragment等类型都建立一个类似这样的基类,这样一来你就可以将这种思想运用到更广阔的范围了。

最后,从整体效果来说,MVP是开发过程中非常值得推荐的构架模式,他能够将各组件进行解偶,并且带来了良好的扩展性、可测试性、稳定性、可维护性,同时使得每个类型的职责相对单一、简单,便面了大量的“胖”程序存在,例如数千行的Activity类。他有效的业务逻辑、数据处理等工作从Activity等View元素中抽离出来,使得每个类尽可能简单,同时每个模块能够独立进行演化。它的思想也非常好的体现了面向对象的设计原则。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: