天天看点

android 应用模式之mvp

说到mvp就不得不提到mvc,做过j2ee的猿友们肯定知道mvc是个什么东西。mvc即 model、view、controller, 那mvp就model、view、presenter。model用于提供数据模型,view用于显示数据,当然presenter也就用来处理业务逻辑并将数据显示数据到view上了,它是model和view的桥梁。

题外话,其实在15年的时候,我们公司的项目就采用mvp,当时没时间写,最近看时间不紧,就分享下

我将整个项目分为三个module,如下图

android 应用模式之mvp

其实这种结构我是不太喜欢的,我喜欢在app的根目录下,新建一个liabary文件,这里放第三方的库工程;

一、数据处理模块domain(包含model),这里的domain命名只是我喜欢这样把数据处理相关的东西都放在这里。

android 应用模式之mvp

      servicemanager用于向外提供数据的入口(其他类代码在前面博文中已提及)

package com.micky.retrofitrxandroiddragger2.domain.service;  

import retrofit.gsonconverterfactory;  

import retrofit.retrofit;  

import retrofit.rxjavacalladapterfactory;  

public class servicemanager {  

    private static final string endpoint = "http://ip.taobao.com";  

    private static class servicemanagerholder {  

        private static final servicemanager instance = new servicemanager();  

    }  

    private servicemanager() {}  

    public static final servicemanager getinstance() {  

        return servicemanagerholder.instance;  

    private apiservice mapiservice = null;  

    public apiservice getapiservice() {  

        if (mapiservice == null) {  

            retrofit retrofit = new retrofit.builder()  

                    .baseurl(endpoint)  

                    .addconverterfactory(gsonconverterfactory.create())  

                    .addcalladapterfactory(rxjavacalladapterfactory.create())  

                    .build();  

            mapiservice = retrofit.create(apiservice.class);  

            return mapiservice;  

        }  

        return mapiservice;  

}  

注:我们在这个manager里面主要做一些网络请求,业务处理,数据组装...

二、view和presenter模块

      为了方便管理我将view和presenter相关类都放在presentation模块中

android 应用模式之mvp

view接口

public interface mainview {  

    void showprogress();  

    void hideprogress();  

    void setiptext(string text);  

presenter接口

package com.micky.retrofitrxandroiddragger2.presenter;  

public interface mainpresenter extends basepresenter {  

    void getipinfo(string ip);  

presenter实现类

package com.micky.retrofitrxandroiddragger2.presenter.impl;  

import android.text.textutils;  

import android.util.log;  

import android.widget.toast;  

import com.micky.retrofitrxandroiddragger2.baseapplication;  

import com.micky.retrofitrxandroiddragger2.r;  

import com.micky.retrofitrxandroiddragger2.domain.service.servicemanager;  

import com.micky.retrofitrxandroiddragger2.domain.service.response.getipinforesponse;  

import com.micky.retrofitrxandroiddragger2.presenter.mainpresenter;  

import com.micky.retrofitrxandroiddragger2.presenter.impl.basepresenterimpl;  

import com.micky.retrofitrxandroiddragger2.ui.view.mainview;  

import rx.subscriber;  

import rx.android.schedulers.androidschedulers;  

import rx.schedulers.schedulers;  

public class mainpresenterimpl extends basepresenterimpl implements mainpresenter {  

    private static final string tag = "tag";  

    private mainview mmainview;  

    public mainpresenterimpl(mainview mainview) {  

        mmainview = mainview;  

    @override  

    public void getipinfo(string ip) {  

        if (textutils.isempty(ip)) {  

            toast.maketext(baseapplication.getcontext(), r.string.input_tip_ip, toast.length_short).show();  

            return;  

        mmainview.setiptext("");  

        mmainview.showprogress();  

        servicemanager.getinstance().getapiservice().getipinfo(ip)  

                .subscribeon(schedulers.io())  

                .observeon(androidschedulers.mainthread())  

                .subscribe(new subscriber<getipinforesponse>() {  

                    @override  

                    public void oncompleted() {  

                        mmainview.hideprogress();  

                    }  

                    public void onerror(throwable e) {  

                        log.e(tag, e.getmessage(), e);  

                        mmainview.setiptext(baseapplication.getcontext().getstring(r.string.network_error));  

                    public void onnext(getipinforesponse getipinforesponse) {  

                        mmainview.setiptext(getipinforesponse.data.country + " " + getipinforesponse.data.area);  

                });  

mainactivity

package com.micky.retrofitrxandroiddragger2.ui.activity;  

import android.os.bundle;  

import android.support.design.widget.floatingactionbutton;  

import android.support.v7.app.appcompatactivity;  

import android.support.v7.widget.toolbar;  

import android.view.view;  

import android.view.menu;  

import android.view.menuitem;  

import android.widget.edittext;  

import android.widget.progressbar;  

import android.widget.textview;  

import com.micky.retrofitrxandroiddragger2.presenter.impl.mainpresenterimpl;  

public class mainactivity extends appcompatactivity implements mainview {  

    private edittext metip;  

    private textview mtvcontent;  

    private progressbar mprogressbar;  

    private mainpresenter mmainpresenter;  

    protected void oncreate(bundle savedinstancestate) {  

        super.oncreate(savedinstancestate);  

        setcontentview(r.layout.activity_main);  

        toolbar toolbar = (toolbar) findviewbyid(r.id.toolbar);  

        setsupportactionbar(toolbar);  

        metip = (edittext) findviewbyid(r.id.et_ip);  

        mtvcontent = (textview) findviewbyid(r.id.tv_content);  

        mprogressbar = (progressbar) findviewbyid(r.id.progress_bar);  

        mmainpresenter = new mainpresenterimpl(this);  

        floatingactionbutton fab = (floatingactionbutton) findviewbyid(r.id.fab);  

        fab.setonclicklistener(new view.onclicklistener() {  

            @override  

            public void onclick(view view) {  

                mmainpresenter.getipinfo(metip.gettext().tostring());  

            }  

        });  

    public boolean oncreateoptionsmenu(menu menu) {  

        getmenuinflater().inflate(r.menu.menu_main, menu);  

        return true;  

    public boolean onoptionsitemselected(menuitem item) {  

        int id = item.getitemid();  

        if (id == r.id.action_settings) {  

            return true;  

        return super.onoptionsitemselected(item);  

    public void showprogress() {  

        mprogressbar.setvisibility(view.visible);  

    public void hideprogress() {  

        mprogressbar.setvisibility(view.gone);  

    public void setiptext(string text) {  

        mtvcontent.settext(text);  

     ok,代码基本完了,看了上述代码大家也许都会说以前就在一个类里面就搞定的功能,现在怎么多出这么多接口、实现类啊。别急我刚看到这个mvp的时候也这么想,几度写着写着都把它抛之脑后,这类都多得看不过来了。

    仔细研究下不难发现这m、v、p三者的关系还是挺清晰的。

android 应用模式之mvp

好了就到这里,你也赶快试试吧