Android開發中MVP模式淺析,androidmvp模式淺析
目前為止,MVP的使用還沒有一個標準,在此先記錄一下目前學習到的一些Android中使用MVP的知識。
按傳統的方式開發,經常會使Activity中混雜著UI互動,商務邏輯等流程。而MVP模式能巧妙的解決這個問題。先直接上一個小例子吧。
/** * 定義一個對UI組件進行操作的介面,讓Activity實現這個介面 * @author Quinn * @date 2015-5-9 */public interface LoginView { public void showProgress(); public void hideProgress(); public void setUsernameError(); public void setPasswordError(); public void navigateToHome();}
/** * Activity需要實現View介面,並且持有一個Presenter對象,將邏輯處理都轉到Presenter * @author Quinn * @date 2015-5-9 */public class LoginActivity extends Activity implements LoginView,View.OnClickListener {private ProgressBar progressBar;private EditText username;private EditText password;private LoginPresenter presenter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_login);progressBar = (ProgressBar) findViewById(R.id.progress);username = (EditText) findViewById(R.id.username);password = (EditText) findViewById(R.id.password);findViewById(R.id.button).setOnClickListener(this);presenter = new LoginPresenterImpl(this);}@Overridepublic void showProgress() {progressBar.setVisibility(View.VISIBLE);}@Overridepublic void hideProgress() {progressBar.setVisibility(View.GONE);}@Overridepublic void setUsernameError() {username.setError(getString(R.string.username_error));}@Overridepublic void setPasswordError() {password.setError(getString(R.string.password_error));}@Overridepublic void navigateToHome() {startActivity(new Intent(this, MainActivity.class));finish();}@Overridepublic void onClick(View v) {presenter.validateCredentials(username.getText().toString(), password.getText().toString());}}
/** * Presenter介面,聲明了登陸的邏輯處理介面 * @author Quinn * @date 2015-5-9 */public interface LoginPresenter { public void validateCredentials(String username, String password);}
/** * Presenter的具體實現,持有View和Interator的引用,處理UI響應,資料處理等 * 其中Interactor代表了Model,可以通過不同的Interactor處理各個Use case * @author Quinn * @date 2015-5-9 */public class LoginPresenterImpl implements LoginPresenter,OnLoginFinishedListener {private LoginView loginView;private LoginInteractor loginInteractor;public LoginPresenterImpl(LoginView loginView) {this.loginView = loginView;this.loginInteractor = new LoginInteractorImpl();}@Overridepublic void validateCredentials(String username, String password) {loginView.showProgress();loginInteractor.login(username, password, this);}@Overridepublic void onUsernameError() {loginView.setUsernameError();loginView.hideProgress();}@Overridepublic void onPasswordError() {loginView.setPasswordError();loginView.hideProgress();}@Overridepublic void onSuccess() {loginView.navigateToHome();}}
/** * 處理登陸的介面 * @author Quinn * @date 2015-5-9 */public interface LoginInteractor { public void login(String username, String password, OnLoginFinishedListener listener);}
/** * 登陸Interactor的實現,在Presenter中持有它的引用 * @author Quinn * @date 2015-5-9 */public class LoginInteractorImpl implements LoginInteractor { @Override public void login(final String username, final String password, final OnLoginFinishedListener listener) { // Mock login. I'm creating a handler to delay the answer a couple of seconds new Handler().postDelayed(new Runnable() { @Override public void run() { boolean error = false; if (TextUtils.isEmpty(username)){ listener.onUsernameError(); error = true; } if (TextUtils.isEmpty(password)){ listener.onPasswordError(); error = true; } if (!error){ listener.onSuccess(); } } }, 2000); }}
/** * 登陸結果回調介面 * @author Quinn * @date 2015-5-9 */public interface OnLoginFinishedListener { public void onUsernameError(); public void onPasswordError(); public void onSuccess();}
稍微分析一下上面得代碼介面。
View層:是圖層,主要是定義一個View介面,聲明各種處理UI組件的方法,然後由Activity實現,但是最後真正的調用時在Presenter中,因為在Activity中定義Presenter時將View作為建構函式的參數傳遞給了Presenter。
Presenter層:業務層,響應UI層,資料層,邏輯處理,持有Interactor引用。
Model/Interactor層:這裡的Interactor就是Model層,它定義具體的行為介面供Presenter調用,可以實現不同的Interactor處理不同的Use case。比如資料讀取,資料存放區,網路請求等等操作。
參考資料:
http://antonioleiva.com/mvp-android/
https://github.com/antoniolg/androidmvp