说到mvp就不得不提到mvc,做过j2ee的猿友们肯定知道mvc是个什么东西。mvc即 model、view、controller, 那mvp就model、view、presenter。model用于提供数据模型,view用于显示数据,当然presenter也就用来处理业务逻辑并将数据显示数据到view上了,它是model和view的桥梁。
题外话,其实在15年的时候,我们公司的项目就采用mvp,当时没时间写,最近看时间不紧,就分享下
我将整个项目分为三个module,如下图
其实这种结构我是不太喜欢的,我喜欢在app的根目录下,新建一个liabary文件,这里放第三方的库工程;
一、数据处理模块domain(包含model),这里的domain命名只是我喜欢这样把数据处理相关的东西都放在这里。
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模块中
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三者的关系还是挺清晰的。
好了就到这里,你也赶快试试吧