Android MVP 實踐之路(理解篇)
阿新 • • 發佈:2018-11-19
一.簡單介紹下MVP
1.什麼是mvp?
簡稱:MVP 全稱:Model-View-Presenter ;MVP 是從經典的模式MVC演變而來,它們的基本思想有相通的地方:Controller/Presenter負責邏輯的處理,Model提供資料,View負責顯示。
2.mvp 與mvc 的區別?
在MVP中View並不直接使用Model,它們之間的通訊是通過Presenter (MVC中的Controller)來進行的,所有的互動都發生在Presenter內部,而在MVC中View會直接從Model中讀取資料而不是通過 Controller。
3.優點和缺點介紹
優點:
1、模型與檢視完全分離,我們可以修改檢視而不影響模型
2、可以更高效地使用模型,因為所有的互動都發生在一個地方——Presenter內部
3、我們可以將一個Presenter用於多個檢視,而不需要改變Presenter的邏輯。這個特性非常的有用,因為檢視的變化總是比模型的變化頻繁。
4、如果我們把邏輯放在Presenter中,那麼我們就可以脫離使用者介面來測試這些邏輯(單元測試)
缺點:
由於對檢視的渲染放在了Presenter中,所以檢視和Presenter的互動會過於頻繁。還有一點需要明白,如果Presenter過多地渲染了檢視,往往會使得它與特定的檢視的聯絡過於緊密。一旦檢視需要變更,那麼Presenter也需要變更了。比如說,原本用來呈現Html的Presenter現在也需要用於呈現Pdf了,那麼檢視很有可能也需要變更。
二.看下實現的效果圖
三.接下來是程式碼實現的過程
1.從建立開始
第1步:開啟Android Studio 然後新建一個工程;
第2步:在工程中,新建三個包,分個層,分別是modle、view、presenter
第3步:思考下我們要實現的功能,模擬網路請求,然後點選Button,實現頁面上的TextView的文字改變,這中間我們用Handler模擬一下網路請求
第4步:思考一下我們在MVC的時候,Activity要實現的方法:
a.點選按鈕請求資料 b.當資料請求成功後,呼叫此介面顯示資料 c.當資料請求失敗後,呼叫此介面提示 d.當資料請求異常,呼叫此介面提示 e.顯示正在載入進度框 f.隱藏正在載入進度框
第5步:根據上面分析在MVC中所要實現的方法,我們來實現在MVP的View層的介面中需要實現這幾個方法;
public interface MvpView {
/**
* 顯示正在載入進度框
*/
void showLoading();
/**
* 隱藏正在載入進度框
*/
void hideLoading();
/**
* 當資料請求成功後,呼叫此介面顯示資料
* @param data 資料來源
*/
void showData(String data);
/**
* 當資料請求失敗後,呼叫此介面提示
* @param msg 失敗原因
*/
void showFailureMessage(String msg);
/**
* 當資料請求異常,呼叫此介面提示
*/
void showErrorMessage();
}
第6步:我們的View層好像寫好了,接下來我們來想想我們的model層吧。其實很簡單,我們說了model層是資料獲取傳輸的層,那麼在model中建立個model類,然後寫一個獲取資料的靜態方法,這是獲取到資料了,那麼我們獲取到的資料怎麼傳遞給我們的Presenter呢? 不饒了,利用介面Callback方法來進行資料的回撥;兩段程式碼如下:
MvpModel類
public class MvpModel {
/**
* 獲取網路介面資料
*
*
* @param param 請求引數
* @param callback 資料回撥介面
*/
public static void getNetData(final String param, final MvpCallback callback) {
// 利用postDelayed方法模擬網路請求資料的耗時操作
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
callback.onSuccess("模擬網路請求得到的資料");
callback.onComplete();
}
}, 2000);
}
}
MvpCallback類
public interface MvpCallback {
/**
* 資料請求成功
*
* @param data 請求到的資料
*/
void onSuccess(String data);
/**
* 使用網路API介面請求方式時,雖然已經請求成功但是由
* 於{@code msg}的原因無法正常返回資料。
*/
void onFailure(String msg);
/**
* 請求資料失敗,指在請求網路API介面請求方式時,出現無法聯網、
* 缺少許可權,記憶體洩露等原因導致無法連線到請求資料來源。
*/
void onError();
/**
* 當請求資料結束時,無論請求結果是成功,失敗或是丟擲異常都會執行此方法給使用者做處理,通常做網路
* 請求時可以在此處隱藏“正在載入”的等待控制元件
*/
void onComplete();
}
第7步:如上方法實現後,那我們的View和model層都有了,我們要實現presenter層,這個是作為中間轉換成,要實現model層和view層的方法;所以要傳遞一個實現View介面的視窗檢視進來,然後呼叫model層的資料獲取方法,將model層的資料展示給我我們的view哦;啥都不說了,程式碼看一眼就懂了;
MvpPresenter 類
public class MvpPresenter {
// View介面
private MvpView mView;
public MvpPresenter(MvpView view) {
this.mView = view;
}
/**
* 獲取網路資料
*
* @param params 引數
*/
public void getData(String params) {
//顯示正在載入進度條
mView.showLoading();
// 呼叫Model請求資料
MvpModel.getNetData(params, new MvpCallback() {
@Override
public void onSuccess(String data) {
//呼叫view介面顯示資料
mView.showData(data);
}
@Override
public void onFailure(String msg) {
//呼叫view介面提示失敗資訊
mView.showFailureMessage(msg);
}
@Override
public void onError() {
//呼叫view介面提示請求異常
mView.showErrorMessage();
}
@Override
public void onComplete() {
// 隱藏正在載入進度條
mView.hideLoading();
}
});
}
}
第8步:是不是很刺激?看看自己都寫了什麼❓,下面就是見證奇蹟的時刻,我們的mainActivity中應該如何編寫?佈局檔案很簡單,就是一個線性佈局,裡面一個Button,一個TextView;在Activity中,要例項化Presenter類,並且那幾個方法都在Presenter中實現了哦,在來一個dialog展示框就行了,對不對?上程式碼看看吧,會好理解一些;
MainActivity 類
public class MainActivity extends AppCompatActivity implements MvpView {
private ProgressDialog progressDialog;
private MvpPresenter presenter;
private TextView textview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textview = findViewById(R.id.textview);
progressDialog = new ProgressDialog(this);
progressDialog.setCancelable(false);
progressDialog.setMessage("正在載入資料");
presenter = new MvpPresenter(this);
}
/**
* 點選事件
* @param view
*/
public void getDatas(View view) {
presenter.getData("normal");
}
/**
* 顯示正在載入進度框
*/
@Override
public void showLoading() {
if (!progressDialog.isShowing()) {
progressDialog.show();
}
}
/**
* 隱藏正在載入進度框
*/
@Override
public void hideLoading() {
if (progressDialog.isShowing()) {
progressDialog.dismiss();
}
}
/**
* 當資料請求成功後,呼叫此介面顯示資料
*
* @param data 資料來源
*/
@Override
public void showData(String data) {
textview.setText(data);
}
/**
* 當資料請求失敗後,呼叫此介面提示
*
* @param msg 失敗原因
*/
@Override
public void showFailureMessage(String msg) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
}
/**
* 當資料請求異常,呼叫此介面提示
*/
@Override
public void showErrorMessage() {
Toast.makeText(this, "網路請求資料出現異常", Toast.LENGTH_SHORT).show();
}
}
四.如上就是實現的過程,這是一個簡單的demo,幫助我們理解和熟悉MVP到底是什麼玩意,真的想要在專案中實踐,還需要花費一番功夫來弄。這個簡單的demo先分享給大家,更多的MVP的內容,我會在下面的文章中更新,歡迎大家一起交流,感謝大家;
最後附上一個GitHub的 下載地址
喜歡的也可以關注下我的微信公眾號“七秒的空間”