詳解Android中的MVP架構分解和實現(xiàn)
1、概述
傳統(tǒng)的Android開發(fā)架構一般是MVC模式,
- Model:業(yè)務邏輯和實體模型
- View:對應于布局文件
- Controllor:對應于Activity
單獨從邏輯看起來非常好,與我們做Web開發(fā)時,開發(fā)模式類似,但在實際開發(fā)中,View對應于布局文件,實際上關于該布局文件中的數(shù)據(jù)綁定的操作,事件處理的代碼都在Activity中,Activity既像View又像Controller(MVVP架構中包括數(shù)據(jù)綁定),導致Activity中職責太重,耦合度大。修改和維護起來非常麻煩。

2、MVP介紹

MVP架構中,View 對應于Activity,負責View的繪制以及與用戶交互
Model 依然是業(yè)務邏輯和實體模型,Presenter 負責完成View于Model間的交互。
(1)Model層
模型層之中做的工作是具體業(yè)務邏輯處理的實現(xiàn),都伴隨著程序中各種數(shù)據(jù)的處理,復雜一些的就需要實現(xiàn)一個Interface來松耦合了。
(2)View層
視圖層體現(xiàn)的很輕薄,負責顯示數(shù)據(jù)、提供友好界面跟用戶交互就行。MVP下Activity和Fragment體現(xiàn)在了這一 層,Activity一般也就做加載UI視圖、設置監(jiān)聽再交由Presenter處理的一些工作,所以也就需要持有相應Presenter的引用。處理一些基本UI邏輯,判斷是否為空。
(3)Presenter層
Presenter這一層處理著程序各種邏輯的分發(fā),收到View層UI上的反饋命令、定時命令、系統(tǒng)命令等指令后分發(fā)處理邏輯交由Model層做具體的業(yè)務操作。
MVP架構和MVC架構區(qū)別:

MVC中是允許Model和View進行交互的,而MVP中,Model與View之間的交互由Presenter完成。還有一點就是Presenter與View之間的交互是通過接口的。
3、MVP實現(xiàn)
百說不如一做。實現(xiàn)一個簡單的登錄操作。
項目結構如下:

(1)Model層實現(xiàn)
首先實現(xiàn)User實體類:
package com.chunsoft.blogcontent.bean;
/**
* Developer:chunsoft on 2017/2/7 11:19
* Content:實體類
*/
public class User {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
model層主要實現(xiàn)業(yè)務邏輯處理,在本文案例中,主要邏輯處理就是登錄,抽取了一個接口和一個實現(xiàn)類,在login操作,模擬登錄操作,Thread.sleep()模擬耗時,由于是耗時操作,通過一個回調(diào)接口通知登錄狀態(tài)。
model層接口:
package com.chunsoft.blogcontent.model;
import com.chunsoft.blogcontent.RequestCallback;
import com.chunsoft.blogcontent.bean.User;
/**
* Developer:chunsoft on 2017/2/7 11:30
* Email:chun_soft@qq.com
* Content:Model層主要處理業(yè)務方法和實體模型
*/
public interface LoginModel {
void login(String username, String password, RequestCallback<User> callback);
}
model層接口實現(xiàn):
package com.chunsoft.blogcontent.model.impl;
import com.chunsoft.blogcontent.RequestCallback;
import com.chunsoft.blogcontent.bean.User;
import com.chunsoft.blogcontent.model.LoginModel;
/**
* Developer:chunsoft on 2017/2/7 11:31
* Content:Model層的實現(xiàn)
*/
public class LoginModelImpl implements LoginModel{
@Override
public void login(final String username, final String password, final RequestCallback<User> callback) {
//模仿登錄操作
new Thread() {
@Override
public void run() {
try {
Thread.sleep(2*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if ("chunsoft".equals(username) && "123456".equals(password)) {
User user = new User();
user.setUsername(username);
user.setPassword(password);
callback.onSuccess(user);
} else {
callback.onFailure("登錄失敗");
}
}
}.start();
}
}
回調(diào)接口:
package com.chunsoft.blogcontent;
/**
* Developer:chunsoft on 2017/2/7 11:35
* Content:回調(diào)接口
*/
public interface RequestCallback<T> {
void onSuccess(T datas);
void onFailure(String msg);
}
(2)View層實現(xiàn)
對于View層接口定義,首先考慮功能上的操作,然后考慮:
- 該操作需要什么?(getUserName等)
- 該操作的結果,對應的反饋?(toMainActivity等)
- 該操作過程中交互友好?( showLoading)
view層接口:
package com.chunsoft.blogcontent.view;
import com.chunsoft.blogcontent.bean.User;
/**
* Developer:chunsoft on 2017/2/7 11:54
* Email:chun_soft@qq.com
* Content:view層接口
*/
public interface LoginView {
String getUserName();
String getPassword();
void showLoading();
void hideLoading();
void toMainActvity(User user);
void showFailedError(String msg);
}
view層實現(xiàn),其實就是Activity,可以看到Activity的代碼量大大減少,且邏輯清晰:
package com.chunsoft.blogcontent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.Toast;
import com.chunsoft.blogcontent.bean.User;
import com.chunsoft.blogcontent.presenter.impl.LoginPresenterImpl;
import com.chunsoft.blogcontent.view.LoginView;
public class MainActivity extends AppCompatActivity implements LoginView{
private EditText et_mobile,et_password;
private ProgressBar pb;
private Button btn_login;
private LoginPresenterImpl mLoginPresenter = new LoginPresenterImpl(this);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_mobile = (EditText) findViewById(R.id.et_mobile);
et_password = (EditText) findViewById(R.id.et_password);
pb = (ProgressBar) findViewById(R.id.pb);
btn_login = (Button) findViewById(R.id.btn_login);
btn_login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mLoginPresenter.login();
}
});
}
@Override
public String getUserName() {
return et_mobile.getText().toString();
}
@Override
public String getPassword() {
return et_password.getText().toString();
}
@Override
public void showLoading() {
pb.setVisibility(View.VISIBLE);
}
@Override
public void hideLoading() {
pb.setVisibility(View.INVISIBLE);
}
@Override
public void toMainActvity(User user) {
Toast.makeText(this,user.getUsername() + "登錄成功",Toast.LENGTH_SHORT).show();
}
@Override
public void showFailedError(String msg) {
Toast.makeText(this,msg,Toast.LENGTH_SHORT).show();
}
}
(3)Presenter層實現(xiàn)
Presenter層是Model層和View層的橋梁,本文中依然抽象出一個接口和一個實現(xiàn)類,定義時主要看該功能有什么操作,例如,登錄:
Presenter接口:
package com.chunsoft.blogcontent.presenter;
/**
* Developer:chunsoft on 2017/2/7 11:49
* Content:Presenter層接口
*/
public interface LoginPresenter {
void login();
}
Presenter層實現(xiàn):
package com.chunsoft.blogcontent.presenter.impl;
import android.os.Handler;
import com.chunsoft.blogcontent.RequestCallback;
import com.chunsoft.blogcontent.bean.User;
import com.chunsoft.blogcontent.model.LoginModel;
import com.chunsoft.blogcontent.model.impl.LoginModelImpl;
import com.chunsoft.blogcontent.presenter.LoginPresenter;
import com.chunsoft.blogcontent.view.LoginView;
/**
* Developer:chunsoft on 2017/2/7 11:50
* Content:Presenter層實現(xiàn)
*/
public class LoginPresenterImpl implements LoginPresenter {
private LoginView loginView;
private LoginModel loginModel;
private Handler mHandler = new Handler();
//在構造函數(shù)中初始化
public LoginPresenterImpl(LoginView loginView) {
this.loginModel = new LoginModelImpl();
this.loginView = loginView;
}
@Override
public void login() {
loginView.showLoading();
loginModel.login(loginView.getUserName(), loginView.getPassword(), new RequestCallback<User>() {
@Override
public void onSuccess(final User datas) {
//登錄成功
mHandler.post(new Runnable() {
@Override
public void run() {
loginView.toMainActvity(datas);
loginView.hideLoading();
}
});
}
@Override
public void onFailure(final String msg) {
//登錄失敗
mHandler.post(new Runnable() {
@Override
public void run() {
loginView.showFailedError(msg);
loginView.hideLoading();
}
});
}
});
}
}
Presenter層是Model層和View層的橋梁,Model層和View層不直接通信,所以Presenter層需要Model層和View層的實現(xiàn)類,從View層中獲取重要參數(shù),交給Model 層調(diào)用業(yè)務邏輯處理,執(zhí)行后的結果和反饋再交給View層去展示。
本文是簡單的用MVP架構實現(xiàn)登錄操作,而目前主流開發(fā),將Rxjava、Retrofit和MVP結合進行開發(fā),邏輯更加清晰,下篇文章將詳細介紹這部分實現(xiàn)。
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
- Android 架構之數(shù)據(jù)庫框架搭建
- Android Jetpack架構組件Lifecycle詳解
- Android Jetpack架構組件 ViewModel詳解
- Android登錄代碼MVP架構詳解
- Android應用架構思想分析
- Android 生命周期架構組件使用方法
- Android架構組件Room的使用詳解
- Android視圖控件架構分析之View、ViewGroup
- 淺析Android系統(tǒng)的架構以及程序項目的目錄結構
- Android App的運行環(huán)境及Android系統(tǒng)架構概覽
- Android操作系統(tǒng)的架構設計分析
- Android 架構之數(shù)據(jù)庫框架升級
相關文章
詳解Java編程中的反射在Android開發(fā)中的應用
這篇文章主要介紹了詳解Java編程中的反射在Android開發(fā)中的應用,主要來獲取安卓系統(tǒng)的屬性值,需要的朋友可以參考下2015-07-07
Android基于HttpUrlConnection類的文件下載實例代碼
本文通過實例代碼給大家介紹了Android基于HttpUrlConnection類的文件下載功能,非常不錯,具有參考借鑒價值,需要的的朋友參考下吧2017-09-09
Android自定義PopupWindow仿點擊彈出分享功能
這篇文章主要為大家詳細介紹了Android自定義PopupWindow仿點擊彈出分享功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-02-02
Android FTP 多線程斷點續(xù)傳下載\上傳的實例
本篇文章主要介紹了Android FTP 多線程斷點續(xù)傳下載\上傳的實例,具有一定的參考價值,有興趣的可以了解一下2017-08-08
Android 使用 RxJava2 實現(xiàn)倒計時功能的示例代碼
本篇文章主要介紹了Android 使用 RxJava2 實現(xiàn)倒計時功能的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-03-03
Android實現(xiàn)在ServiceManager中加入自定義服務的方法詳解
這篇文章主要介紹了Android實現(xiàn)在ServiceManager中加入自定義服務的方法,結合實例形式分析了Android開發(fā)中ServiceManager自定義服務的相關創(chuàng)建與使用方法,需要的朋友可以參考下2017-08-08
Android的Fragment的生命周期各狀態(tài)和回調(diào)函數(shù)使用
這篇文章主要介紹了Android的Fragments的生命周期各狀態(tài)和回調(diào)函數(shù)使用,Fragments的生命周期與Activity息息相關,需要的朋友可以參考下2016-02-02
深入淺析Android手機衛(wèi)士保存密碼時進行md5加密
一般的手機沒有root權限,進不去data/data目錄,當手機刷機了后,擁有root權限,就可以進入data/data目錄,查看我們保存的密碼文件,因此我們需要對存入的密碼進行MD5加密,接下來通過本文給大家介紹Android手機衛(wèi)士保存密碼時進行md5加密,需要的朋友一起學習吧2016-04-04
Flutter實現(xiàn)PopupMenu彈出式菜單按鈕詳解
這篇文章主要介紹了Flutter實現(xiàn)PopupMenu彈出式菜單按鈕,PopupMenuButton是一個用于創(chuàng)建彈出菜單的小部件,當用戶點擊觸發(fā)按鈕時,PopupMenuButton會在屏幕上方或下方彈出一個菜單,感興趣想要詳細了解可以參考下文2023-05-05

