android安卓mvp架構簡單教程(附登錄註冊小demo)

MVP簡介

MVP的出發點是關注點分離,將視圖和業務邏輯解耦。Model-View-Presenter三個部分可以簡單理解爲:

  • Model是將在視圖中顯示的數據。
  • View是顯示數據(model)的界面,同時將用戶指令(事件)發送給Presenter來處理。View通常含有Presenter的引用。在Android中Activity,Fragment和ViewGroup都扮演視圖的角色。
  • Presenter是中間人,同時有兩者的引用。請注意單詞model非常有誤導性。它應該是獲取或處理model的業務邏輯。例如:如果你的數據庫表中存儲着User,而你的視圖想顯示用戶列表,那麼Presenter將有一個數據庫業務邏輯(例如DAO)類的引用,Presenter通過它來查詢用戶列表。
我們大致瞭解到了MVP模式理論基礎是怎麼的,那麼現在我們通過一個登錄註冊的demo來進行分析,
在我們還是小白或者不懂mvx結構的時候,我們一般情況下都會將視圖處理,邏輯業務,數據請求等全部都放在activity處理,這就導致了整個activity臃腫不堪,並且不便與修改等操作。基本上就是這個樣子。
public class RegisterActivity extend AppCompatActivity{

@Override
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_register);
//依賴了黃油刀,並且自定義了dialogfragment來提示用戶操作是否成功
}
@OnClick(R.id.btn_Register)
public void onClick() {

// 賬號和密碼是否符合規範
if (RegexUtils.verifyUsername(mUserName)!=RegexUtils.VERIFY_SUCCESS){

// 賬號不合規範時顯示一個對話框提示
AlertDialogFragment.getInstances(getString(R.string.username_error),getString(R.string.username_rules))
.show(getSupportFragmentManager(),"usernameError");
return;
}
// 密碼不合規範時顯示一個另一個對話框提示
if (RegexUtils.verifyPassword(mPassword)!=RegexUtils.VERIFY_SUCCESS){
AlertDialogFragment.getInstances(getString(R.string.password_error),getString(R.string.password_rules))
.show(getSupportFragmentManager(),"passwordError");
return;
}

// 如果都符合正確註冊規則,進行註冊的業務,我們寫一個異步任務來模擬登錄的網絡請求
new AsyncTask<Void, Integer, Void>() {
@Override
protected void onPreExecute() {
super.onPreExecute();
// 進度條展示
showProgress();
}
@Override
protected Void doInBackground(Void... params) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
// 拿到數據處理UI
// 隱藏進度、顯示信息、跳轉頁面
hideProgress();
showMessage("註冊成功");
navigateToHome();
}
}.execute();

}
這樣看起來並沒有什麼不對,但是慢慢的你會發現,當本activity裏面的代碼、業務邏輯等多起來,出錯之後就不好找錯誤的地方,並且看起來非常不舒服,所以此時,mvp模式就起到了作用了。

首先我們要理清思路
 1. View:Activity裏面,我們需要獲取數據,所以通過一個業務類實現
 2. Presneter:業務類裏面,去執行業務拿到View需要的數據
 3. 拿到數據之後,數據要給視圖View設置上

 我們的目的是想要把視圖和業務分離
 不建議直接拿視圖的對象來操作,接口:接口回調
 在業務過程中視圖的操作:定義一個接口
 
1.註冊的視圖接口
public interface RegisterView {

void showProgress();// 顯示進度

void hideProgress();// 隱藏進度

void showMessage(String msg);// 顯示信息

void navigateToHome();// 跳轉頁面
}
2.將之前我們的activity做成View層
public class RegisterActivity extend AppCompatActivity implements RegisterView{

@Override
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_register);
//依賴了黃油刀,並且自定義了dialogfragment來提示用戶操作是否成功
}
@OnClick(R.id.btn_Register)
public void onClick() {

// 賬號和密碼是否符合規範
if (RegexUtils.verifyUsername(mUserName)!=RegexUtils.VERIFY_SUCCESS){

// 賬號不合規範時顯示一個對話框提示
AlertDialogFragment.getInstances(getString(R.string.username_error),getString(R.string.username_rules))
.show(getSupportFragmentManager(),"usernameError");
return;
}
// 密碼不合規範時顯示一個另一個對話框提示
if (RegexUtils.verifyPassword(mPassword)!=RegexUtils.VERIFY_SUCCESS){
AlertDialogFragment.getInstances(getString(R.string.password_error),getString(R.string.password_rules))
.show(getSupportFragmentManager(),"passwordError");
return;
}

// 如果都符合正確註冊規則,進行註冊的業務
new RegisterPresenter(this).register();
}

3.註冊的業務類
public class RegisterPresenter {

private RegisterView mRegisterView;

public RegisterPresenter(RegisterView registerView) {
mRegisterView = registerView;
}

註冊的業務實現
public void register(){
new AsyncTask<Void, Integer, Void>() {

@Override
protected void onPreExecute() {
super.onPreExecute();
// 進度條展示
mRegisterView.showProgress();
}

@Override
protected Void doInBackground(Void... params) {

try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}

return null;
}

@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);

// 拿到數據處理UI
// 隱藏進度、顯示信息、跳轉頁面
mRegisterView.hideProgress();
mRegisterView.showMessage("註冊成功");
mRegisterView.navigateToHome();

}
}.execute();
}
}
到這裏我們基本實現了註冊的一個請求了,不過可能大家也有點暈了,現在就來給大家解釋一波,首先可以看到我們的View層也就是activity實現了RegisterView這個接口,而這個接口時做什麼的呢,其實就是一個視圖接口,我們在其中定義一些方法,比如顯示隱藏進度條,設置數據等,然後在它的實現類去實現接口中的方法。
我們可以看到,在註冊的時候,當我們的賬號密碼格式正確時,就會走到這一步,new RegisterPresenter(this).register()。這是什麼意思呢?!我們再看一下RegisterPresenter這個業務類,裏面構造要求傳一個視圖對象接口,而我們的activity是實現了這個視圖接口的,所以當我們調用RegisterPresenter的構造時,只需要傳入activity本身就可以了,並且當我們調用業務類中的register()方法時會執行如mRegisterView.navigateToHome()的一些方法,也就是我們構造傳過來的視圖接口的實現類對象.navigateToHome()這個方法,activity這個實現類又是實現了視圖接口中的方法,所以也就等價於activity調用了.navigateToHome()這個方法。
這個時候我們想要的效果有了,業務邏輯與視圖間的分離也實現了,我們也就達到了想要的目的了。登錄的MVP架構也類似,大家可以試一試。
到此,這個簡單的MVP架構講解也就結束了,希望大家多多指正錯誤,謝謝!!!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章