說到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三者的關系還是挺清晰的。
好了就到這裡,你也趕快試試吧