【Android学习】两种MVP模式的学习(一):谷歌例子的简单学习

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012970471/article/details/52658378

关于MVP的介绍网上有很多,身为搬运工的我直接搬来百度百科的,其实想来大家也都知道的。


MVP:

mvp的全称为Model-View-Presenter,Model提供数据,View负责显示,Controller/Presenter负责逻辑的处理。

MVP与MVC有着一个重大的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Presenter (MVC中的Controller)来进行的,所有的交

互都发生在Presenter内部,而在MVC中View会直接从Model中读取数据而不是通过 Controller。


在学习MVP模式的时候,最近比较火的是谷歌的例子:

https://github.com/googlesamples/android-architecture

结构很清晰,用一个契约类将View,Presenter的接口写在里面,这样可以清晰的知道有哪些功能,界面有哪些会有变化,数据有哪些需要处理。 


在Presenter创建时传入到View,同时将自身注入到View中,甚是巧妙。


来看一个小李子:


这是我模仿 掌上英雄联盟做的界面 ,除去 ViewPager中的内容,这个界面有两个地方需要获取数据。

一、轮播图。

二、Tab标签以及 “赛事”和“视频” 这俩悬浮页。

根据Fiddler听到的数据来看 ,轮播图是一个请求,Tab和悬浮页是一个请求。



所以基本步骤就是 ,定义设计Model,BaseView ,BasePresenter。


这里的Model比较简单,看一下就过去了:

model接口:

public interface LoLItemModel {

    Observable<LoLBean> getLoLNewsData(String id, int page, String plat, int version);

    Observable<LoLBean> getLoLBanner( String plat, int version);

    Observable<List<LoLTypeBean>> getLoLType(String plat, int version);
}

model实现类:

public class LoLItemModelImpl implements LoLItemModel {
    @Override
    public Observable<LoLBean> getLoLNewsData(String id, int page,String plat, int version) {
        LoLService service = NetWork.getInstance().create(LoLService.class);
        return service.getNewsLoL(id, page, plat, version);
    }

    @Override
    public Observable<LoLBean> getLoLBanner(String plat, int version) {
        LoLService service = NetWork.getInstance().create(LoLService.class);
        return service.getLoLBanner(plat, version);
    }

    @Override
    public Observable<List<LoLTypeBean>> getLoLType(String plat, int version) {
        LoLService service = NetWork.getInstance().create(LoLService.class);
        return service.getLoLType(plat, version);
    }
}

 Model 是在Presenter中进行实例化操作的。


接着来看BaseView,BasePresenter:


public interface IBaseView<T> {
    void setPresenter(T presenter);
}


public interface IBasePresenter {
        void start();
        void destroy();
}


BasePresenter里面的方法看实际而定,我可能需要初始化一些东西,定义了start(),因为使用RxJava,要考虑生命周期,所以定义一个destroy,在View结束时解绑。


然后就是契约类,这个界面 需要和数据进行交互的 只有设置轮播图,tab页。

所以就暂时先定下两个方法。


public class LoLMainContract {

    public interface View extends IBaseView<Presenter> {
        void initBanner(List<LoLBean.ListBean> bannerUrls);
        void initTabs(List<LoLTypeBean> listbean);
    }


    public interface Presenter extends IBasePresenter {
        void getBannersData();
        void getTabsData();
    }
}


实现Presenter:

在构造函数中 获取View同时将自身传入 View中。

public class LoLMainPresenter implements LoLMainContract.Presenter {
    private LoLMainContract.View mView;
    LoLItemModelImpl lolIml;
    Subscription getBannerSPN;
    Subscription getTabSPN;

    public LoLMainPresenter(LoLMainContract.View mView) {
        this.mView = mView;
        this.mView.setPresenter(this);
        lolIml = new LoLItemModelImpl();
    }

    @Override
    public void getBannersData() {
        getBannerSPN = RxManager.getInstance().doSubscribe(lolIml.getLoLBanner("android", 9705), new Subscriber<LoLBean>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(LoLBean loLTypeBeen) {

                mView.initBanner(loLTypeBeen.getList());
            }
        });

    }

    @Override
    public void getTabsData() {
        getTabSPN = RxManager.getInstance().doSubscribe(lolIml.getLoLType("android", 9705), new Subscriber<List<LoLTypeBean>>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(List<LoLTypeBean> loLTypeBeen) {
                mView.initTabs(loLTypeBeen);
            }
        });
    }

    @Override
    public void start() {
    }

    @Override
    public void destroy() {
        if (getBannerSPN != null)
            getBannerSPN.unsubscribe();
        if (getTabSPN != null)
            getTabSPN.unsubscribe();
    }
}


在View生命周期结束的时候对观察者解绑。


然后就是实现View。

这里是Fragment 做View ,Activity统筹管理View


public class LoLMainFragment extends BaseFragment implements LoLMainContract.View{  }


我们的fragment实现契约类中Presenter的View接口,

声明Presenter并在实现View的方法中赋值:

 private LoLMainContract.Presenter mPresenter;

    @Override
    public void setPresenter(LoLMainContract.Presenter presenter) {
        this.mPresenter = presenter;
    }


获取数据 :

 mPresenter.getBannersData();
 mPresenter.getTabsData();

获取之后会调用View的方法 将返回的数据 在View中显示。



都实现之后就是  最后创建Fragment

 lolMainFragment = new LoLMainFragment();


我们在Fragment的onCreate中创建Presenter的实例,并将自身传入:


 new LoLMainPresenter(this);


这样一个基本的MVP模式就出来了。

这只是练手用的,熟悉MVP构建方法流程。但是我们不能为了架构了使用架构,视具体情况而定。

页面功能多,逻辑复杂,那就得好好思量思量要怎么去实现能让层次清晰,维护方便。

总之,开心就好。


最近学到的还有一种MVP实现方式,挺好的,下篇来学习。

Mosby:https://github.com/sockeqwe/mosby 




阅读更多
换一批

没有更多推荐了,返回首页