天天看點

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

好了就到這裡,你也趕快試試吧