MVP項目架構(gòu) - 讓你的Activity腰圍瘦下來

本章節(jié) 我門將運用上一講Retrofit + RxJava + OkHttp 的簡單封裝的網(wǎng)絡(luò)請求框架

前言

最開始我學習android的時候只會用MVC,MVC相信大家都知道,缺點很明顯,代碼結(jié)構(gòu)很亂,開發(fā)玩一個功能遣铝,幾個月后再回來要改什么功能,一看代碼.我**X******這TM是誰寫的代碼(明明就是自己寫的)莉擒,糾其原因就是因為Activity中同時擁有業(yè)務(wù)和UI邏輯代碼酿炸,不排除還可能存在某些不良編程習慣導致。

那么什么是MVP架構(gòu)?

MVP代表Model涨冀,View和Presenter梁沧。
View層負責處理用戶事件和視圖部分的展示。在Android中蝇裤,它可能是Activity或者Fragment類廷支。
Model層負責訪問數(shù)據(jù)。數(shù)據(jù)可以是遠端的Server API栓辜,本地數(shù)據(jù)庫或者SharedPreference等恋拍。
Presenter層是連接(或適配)View和Model的橋梁。

這么說可能不太好理解 我們看圖說話....(為了使你更好理解 圖片上已經(jīng)備注好了順序和過程)


image.png

注意:以下代碼均取自Fazhi項目wanggang老師的教學代碼 最后我會提供代碼供大家下載 不用擔心!

第一步 準備工作 定義基類接口

1.定義BaseView接口 一些公用的回調(diào)

public interface BaseView {
    void showError(String error);// 展示錯誤的回調(diào)
    void showLoading();// 展示開始請求的Loading
    void hideLoading();// 隱藏開始請求的Loading
    Context getContext();// 用來獲取Context上下文
}

2.定義BaseModel接口

public interface BaseModel {
    // 暫時為空 方便日后更改統(tǒng)一的東西 
}

3.定義BasePresenter接口

public interface BasePresenter{
    // 暫時為空 
}

4.定義BaseActivity藕甩、BaseFragment施敢、Bean類

這些不用在說了把 隨便你門怎么搞 不知道搞就空著放在哪里 預留 相信我總有天你要用的

第二步 繼承第一步定義的基類周荐,并拓展一些該業(yè)務(wù)需求的方法

1.繼承基礎(chǔ)的BaseView

定義出不同業(yè)務(wù)需求下的拓展View接口,為什么我門不直接在BaseView接口中就定義好呢? 主要是為了之后的拓展僵娃,基類我門只做公共的事情概作,而這里很明顯,不同的請求成功后需要返回的參數(shù)的數(shù)量不一樣和參數(shù)類型也可能不同默怨。
在這里我門主要是講Login需求讯榕,那么登陸成功后,需要成功的回調(diào)并且傳遞成功后的參數(shù)給activity匙睹,去顯示提示用戶或者更新UI愚屁,所以我門返回UserBean這個實體類。

public interfaceI LoginView extends BaseView{
    void showHint(UserBean userBean);
}

2.繼承基礎(chǔ)的BaseModel

Model負責訪問數(shù)據(jù) 那么我門定義好登陸的請求接口 用來返回Observable<BaseResponse<UserBean>>這個可觀察者對象

public interface LoginModel extends BaseModel {
    Observable<BaseResponse<UserBean>>(String username, String passwrod);//登陸
}

3.繼承基礎(chǔ)的BasePresenter

Presenter連接View和Model的橋梁 具體待會看代碼就知道為什么了

public interface LoginPresenter {
    void login(String username, String passwrod);//登陸
}

第三步 實現(xiàn)剛才我門拓展的接口

1.實現(xiàn)Model中的login方法痕檬,調(diào)用我門之前封裝好的Retrofit + Rxjava + OkHttp請求庫霎槐,完成請求并返回Observable這個可觀察對象,Presenter這個中間人拿到了觀察者對象就可以處理訂閱結(jié)果梦谜。

public class LoginModelImple implements ILoginModel {
    @Override
    public Observable<BaseResponse<UserBean>> login(String username, String passwrod) {
        HashMap<String, Object> map = new HashMap<>();
        map.put("username", username);
        map.put("password", passwrod);
        RequestBody requestBody = NetRequest.generateReqBody(map);
        return NetRequest.getInstance().getApi().userLogin(requestBody);
    }
}

2.實現(xiàn)PresenterImpl層有具體的請求邏輯(比如事先判斷參數(shù)是否為空這些)丘跌,并且還持有module和view層,可以在命令Model請求完結(jié)果后唁桩,把結(jié)果由View回調(diào)給Activity處理成功失敗的操作碍岔,是名副其實的橋梁....

public class LoginPresenterImpl implements ILoginPresenter {

    private ILoginModel model;
    private ILoginView view;

    public LoginPresenterImpl(ILoginView view) {
        this.model = new LoginModelImple();
        this.view = view;
    }

    @Override
    public void login(String username, String passwrod) {
        if(TextUtils.isEmpty(username)){
            view.showError("賬號不能為空");
            return;
        }
        if(TextUtils.isEmpty(passwrod)){
            view.showError("密碼不能為空");
            return;
        }
        Observable<BaseResponse<UserBean>> login = model.login(username, passwrod);
        login.compose(RxHelper.schedulers())
             .compose(RxHelper.transform())
             .subscribe(new NetSubscriber<UserBean>() {
                 @Override
                 public BaseView getView() {
                     return view;
                 }

                 @Override
                 public void onNext(UserBean userBean) {
                     // 保存值 以備下次驗證使用
                     LocalData.putSessionKey(userBean.getSession_key());
                     LocalData.putUserID(userBean.getUser_id());

                     // 跳轉(zhuǎn)到首頁

                     // 登陸成功 回調(diào)Activity
                     view.showHint(userBean);
                }
            });
    }
}

3.最后當然是看看Activity中到底有多小的腰圍啦!(驚訝!~~好干凈整潔的Activity)

注意View層是Activity實現(xiàn)的 用來接收LoginPresenterImpl這個橋梁中間人反回給我門的結(jié)果哦!

public class LoginActivity extends BaseActivity implements ILoginView {

    @BindView(R.id.login_et_phone)
    EditText loginEtPhone;
    @BindView(R.id.login_et_pasd)
    EditText loginEtPasd;
    private LoginPresenterImpl loginPresenter;
    private LoadingDialog loadingDialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        ButterKnife.bind(this);
        loginPresenter = new LoginPresenterImpl(this);
    }


    @OnClick(R.id.login_btn_login)
    public void onClick() {
        loginPresenter.login(loginEtPhone.getText().toString(), loginEtPasd.getText().toString());
    }

    @Override
    public void showHint(UserBean userBean) {
        ToastUtils.showToast(this, userBean.getNickname());
    }

    @Override
    public void showError(String error) {
        ToastUtils.showErrorToast(this, error);
    }

    @Override
    public void showLoading() {
        loadingDialog = new LoadingDialog(this);
        loadingDialog.show();
    }

    @Override
    public void hideLoading() {
        loadingDialog.dismiss();
    }

    @Override
    public Context getContext() {
        return this;
    }
}

老鐵們,有了第一次寫帖子朵夏,自然也有第二次是把?

fazhi項目框架 Git下載 (向作者wanggang老師致敬)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蔼啦,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子仰猖,更是在濱河造成了極大的恐慌捏肢,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件饥侵,死亡現(xiàn)場離奇詭異鸵赫,居然都是意外死亡,警方通過查閱死者的電腦和手機躏升,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門辩棒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人膨疏,你說我怎么就攤上這事一睁。” “怎么了佃却?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵者吁,是天一觀的道長。 經(jīng)常有香客問我饲帅,道長复凳,這世上最難降的妖魔是什么瘤泪? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮育八,結(jié)果婚禮上对途,老公的妹妹穿的比我還像新娘。我一直安慰自己髓棋,他們只是感情好实檀,可當我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著仲锄,像睡著了一般劲妙。 火紅的嫁衣襯著肌膚如雪湃鹊。 梳的紋絲不亂的頭發(fā)上儒喊,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天,我揣著相機與錄音币呵,去河邊找鬼怀愧。 笑死,一個胖子當著我的面吹牛余赢,可吹牛的內(nèi)容都是我干的芯义。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼妻柒,長吁一口氣:“原來是場噩夢啊……” “哼扛拨!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起举塔,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤绑警,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后央渣,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體计盒,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年芽丹,在試婚紗的時候發(fā)現(xiàn)自己被綠了北启。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片凡桥。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡潮针,死狀恐怖尽狠,靈堂內(nèi)的尸體忽然破棺而出伙单,到底是詐尸還是另有隱情娜睛,我是刑警寧澤症革,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布此衅,位于F島的核電站误褪,受9級特大地震影響春叫,放射性物質(zhì)發(fā)生泄漏肩钠。R本人自食惡果不足惜泣港,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望价匠。 院中可真熱鬧当纱,春花似錦、人聲如沸踩窖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽洋腮。三九已至箫柳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間啥供,已是汗流浹背悯恍。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留伙狐,地道東北人涮毫。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像贷屎,于是被迫代替她去往敵國和親罢防。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容