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

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

作者: 莫离境 | 来源:发表于2016-09-25 20:23 被阅读459次

    关于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中显示。

    都实现之后就是 将V,P实例出来。
    可以将方法放到 Fragment的 create中 。最好封装起来

    new LoLMainPresenter(this);  
    

    这样一个基本的MVP模式就出来了。
    这只是练手用的,熟悉MVP构建方法流程。但是我们不能为了架构了使用架构,视具体情况而定。
    页面功能多,逻辑复杂,那就得好好思量思量要怎么去实现能让层次清晰,维护方便。
    总之,开心就好。

    最近学到的还有一种MVP实现方式,挺好的,下篇来学习。
    Mosby:https://github.com/sockeqwe/mosby

    相关文章

      网友评论

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

          本文链接:https://www.haomeiwen.com/subject/itbfyttx.html