MVP

来源:互联网 发布:公务员网络课程 编辑:程序博客网 时间:2024/06/01 08:04

MVP

关于MVP模式的总结

  • MVP意义
  • 简单实现
  • 隐藏风险
  • 优化

MVP意义

为了解耦合,将页面刷新逻辑和数据加载逻辑区分开来。M->model,进行数据加载;V->view(Activity,Fragment),进行页面业务控制,P->presenter,将M和V结合起来。
V 相当于一台笔记本,如果把音箱、打印机等设备都组装到笔记本上,则显得笔记本比较复杂,体积变大。如果在笔记本上开一个接口,其他设备通过相应数据线(P)连接,那个对于笔记本来说,只要选择要连接的数据线,对于数据线来说,只要选择要连接的设备,对于设备来说,只要做自己的操作,把 数据给数据线,,通过这这种方式,使业务模块化,也更易扩展。MVP 就是这种思想。

MVP简单实现

  • 写View接口

    写一个view 接口,包含一个方法,主要用于展示数据,同时写Activity实现此接口,重写showView 方法,在此方法中进行数据刷新加载

public interface BaseMvpView {    public void showView(List<String> list);}
  • 写model

    model,进行数据加载,包含两个部分,加载数据的方法,和加载完成后数据的回调;

public interface BaseMvpMode {    public void getData(GetDataCompleteInterface getDataCompleteInterface);    public interface GetDataCompleteInterface{        public void complete(List<String>  list);    }}
  • 写presenter

    presenter,每一个Activity 都应有一个对应的presenter,用于进行数据操作模块的选择和数据的回调展示(连接V和M),包含一个执行方法,调用此方法开始加载数据,重写model的回调接口,实现数据回调,调用View 的方法,实现展示

public class MvpPresenter {    private MvpModel mvpModel;    private MvpView mvpView;    public MvpPresenter(MvpView mvpView){        this.mvpView = mvpView;        mvpModel = new MvpModel();    }    public void LoadingData(){        mvpModel.getData(new BaseMvpMode.GetDataCompleteInterface() {            @Override            public void complete(List<String> list) {                  mvpView.showView(list);            }        });    }}

隐藏风险

  • 空指针

    由于页面逻辑和数据加载逻辑分开,当数据加载完成时,如果View已销毁,那么会造成空指针的现象(不该销毁时销毁了)

  • 内存泄露

    因为P 中有V 的引用,当V要销毁时,由于未完成加载,P中有V 的引用导致v不能销毁,造成内存泄露(该销毁时没销毁)

  • 解决方法

    造成上述两种问题的原因,都是因为P和V 的引用的原因,如果在P 中保存为V 的弱引用,那么问题就可以有效避免,因此要对上述MVP逻辑进行优化。

优化

主要思想是让P 中保存V 的弱引用,由于P 和V 的个数、不定,为了避免重复代码操作,分别抽象P 和 V 的基类,在基类中完成引用的绑定。

  • P 基类
    1 得到 V 绑定为弱引用
    2 提供 V 弱引用
    P主要保存引用关系,在基类中将V和P 绑定为弱引用,对于每个继承此基类的P,都能有此操作,避免重复。采用泛型V ,在生成p 时 传过来的V,为V 的实现类,可以正常进行刷新。基类主要做两个操作,绑定引用,提供引用(为保证提供的引用就是当前的V,所以设置V 采用虚方法在子类实现,保证引用为实现类)
public abstract class BaseMvpPresenter <V extends BaseMvpView> {    private WeakReference<V> weakReference;    public void attachView(V baseMvpView){        weakReference = new WeakReference(baseMvpView);    }    public void dettachView(){        if(weakReference!=null){            weakReference.clear();            weakReference = null;        }    }    public V getWeakPerence(){        return weakReference.get();    }}
  • V基类
    1 实例化P
    2 绑定P 和 V
    V基类主要进行 P和V的绑定,需要P实例,由于要绑定的P 实例 不定,因此采用泛型T extents P基类, 又P基类有泛型,需要一个V,因此V基类也要声明出泛型V,传给P基类。对于实例P,因为每个实现类不同,因此P 的 构建应放在实现类中,抽象方法 setBaseMvpPresenter();
public abstract class BaseMvpActivity <V extends BaseMvpView,T extends BaseMvpPresenter<V>>extends AppCompatActivity {    protected T baseMvpPresenter ;    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        baseMvpPresenter =setBaseMvpPresenter();        baseMvpPresenter.attachView((V)this);    }    @Override    protected void onDestroy() {        super.onDestroy();        baseMvpPresenter.dettachView();    }    public abstract T setBaseMvpPresenter();}
  • V实现类

    继承V基类,主要提供V 基类需要的泛型(V ,T),实现虚方法,创建P实例

public class ActivityMvp2 extends BaseMvpActivity <BaseMvpView,MainMvpPresenter>implements BaseMvpView {    private ListView listView;    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_mvp2);        initView();        initData();    }    @Override    public MainMvpPresenter setBaseMvpPresenter() {        return new MainMvpPresenter();    }    private void initData() {        baseMvpPresenter.setModel().loadingData();    }    private void initView() {        listView = (ListView) findViewById(R.id.listview);    }    @Override    public void showView(List<String> list) {        ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,list);        listView.setAdapter(adapter);    }}
  • P实现类

    继承P基类,声明P基类需要的泛型V,同时调用基类中保存的 弱引用(getWeakPerence),实现V 的刷新

public class MainMvpPresenter extends BaseMvpPresenter<BaseMvpView>{    BaseMvpMode baseMvpMode;    public MainMvpPresenter(){    }    public MainMvpPresenter setModel(){        baseMvpMode = new MvpModel();        return  this;    }    public void loadingData(){        baseMvpMode.loadingData(new BaseMvpMode.LoadCompleteInterface() {            @Override            public void loadComplete(List<String> listData) {                getWeakPerence().showView(listData);            }        });    }}

小结

基类的编写和泛型的使用,对于P基类 ,因为不知道要绑定的
V引用是什么,因此 使用泛型V 继承基类 V,,
对于 V基类,因为不知道P类型,因此使用泛型P继承基类P,同时要实例化P,但P不定,因此写虚方法,子类实现。

原创粉丝点击