安卓日记——MVP重构知乎日报

在之前安卓日记——手把手教你做知乎日报已经教大家分析和利用API做出一个简单的知乎日报,源码在github上也收到了5个star
最近我一直很想用一下一直很玄乎的MVP,主要参照谷歌的todo-mvp-rxjava
然后我就想不如就把知乎日报用MVP重构一下吧

我理解中的MVP,以数据库或者网络请求作为M(通常多个共用,所以不单独写)一个Fragment或者Activity作为V,然后把之前的业务逻辑都写在P里。
有人把P当作老板,去指使M和V
而我认为V才是大BOSS,V中创建P,然后把些粗活累活都交给P,P把数据获取外包给M,然后V说我只要看到结果,接收到P传来的结果,就心满意足了

项目可以按照模块分包(登录功能,注册功能……),也可以按照组件分包(P分一类,V分一类……)
我模仿谷歌的todo-mvp-rxjava采用模块分包

这里写图片描述

我看过很多mvp的项目,他们很多是按组件分包的,而且他们都没有一个Contract
在我看来Contract是很有必要的,有了它把职责的分明了,互相调用的方法暴露出来,这样开发的目的会更加明确,分工也更加简单

事不宜迟,现在开始讲如何进行重构
我假设你们都已经懂得如何用我之前的方法做一个知乎日报

1.分析功能模块

这里主要有首页和详情页两个模块

2.写基类

基类不仅节省代码,提高效率,这个不用说了吧

public interface BasePrecenter {
    void subscribe();
    void unsubscribe();
}
public interface BaseView<T extends BasePrecenter> {
    void setPrecenter(T precenter);
}

3.写Contract

Contract中可以不包含M,因为M通常都是公用的,所以单独放,我这Service就是M,主要是网络请求数据

public interface ArticleContract {
    interface View extends BaseView<Precenter>{
        void showAtrticleDetail(String content);
    }
    interface Precenter extends BasePrecenter{
        void loadArticleDetail(int id);
    }
}

4.写Bean和Model

确定好数据的格式和获取的方式
我这里采用的是用retrofit获取数据

public interface ActionService {
    public static String baseUrl="http://news-at.zhihu.com";
    //今日头条
    @GET("/api/4/news/latest")
    Observable<RootBean> getLatestNews();
    //互联网安全
    @GET("/api/4/theme/10")
    Observable<RootBean> getSafety();
    //不准无聊
    @GET("/api/4/theme/11")
    Observable<RootBean> getInterest();
    //体育日报
    @GET("/api/4/theme/8")
    Observable<RootBean> getSport();
    //传入id查看详细信息
    @GET("/api/4/news/{id}")
    Observable<ArticleDetailBean> getNewsDetails(@Path("id") int id);

}

5.然后再写P和V

V中创建P,创建P需要传入V

        //创建P传入V
        precenter=new HomePrecenter(this);
        setPrecenter(precenter);

P中绑定V,并且创建M

 public HomePrecenter(HomeContract.View view){
        //绑定V
        this.view=view;
        //创建M
        service= ServiceFactory.createRetrofitService(ActionService.class,ActionService.baseUrl);
    }

之后主要是一些互相调用Contract中约定好的方法

补充:

P中有subscribe和unsubscribe方法可以与V中的onResume和onPause方法绑定
这样V开始时继续P的业务,暂停时停止P的逻辑

    @Override
    public void onResume() {
        super.onResume();
        precenter.subscribe();
    }

    @Override
    public void onPause() {
        super.onPause();
        precenter.unsubscribe();
    }
}

P中将要执行的业务都添加进CompositeSubscription中,unsubscribe时把CompositeSubscription清空掉

                subscription.add(rootBean
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<RootBean>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(RootBean rootBean) {
                        view.showArticle(rootBean.getStories());
                    }
                }));
 @Override
    public void unsubscribe() {
        subscription.clear();
    }

重构后竟然一次通过了,太兴奋了

效果图

这里写图片描述

源码下载

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,117评论 25 708
  • 前言 看了下上篇博客的发表时间到这篇博客,竟然过了11个月,罪过,罪过。这一年时间也是够折腾的,年初离职跳槽到鹅厂...
    西木柚子阅读 21,290评论 12 184
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,881评论 18 139
  • 外联一家人阅读 149评论 0 0
  • 见 惊艳 目流连 再难思迁 踌躇欲向前 只恐天上人间 悲欢喜怒一线牵 循环往复恨此心坚 花开花落转眼已三年 天人合...
    小随笔阅读 1,084评论 0 2