MVP

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不定,因此写虚方法,子类实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值