## (一).前言:
今天我們的項目繼續更新,今天我們主要講解MVP開發模式以及具體實例。
FastDev4Android框架項目地址:[https://github.com/jiangqqlmj/FastDev4Android](https://github.com/jiangqqlmj/FastDev4Android)
## (二).簡介:
MVP(Model ViewPresenter)模式是著名的MVC(Model ViewController)模式的一個演化版本,目前它在Android應用開發中越來越重要了。初看起來我們會感覺增加了很多類接口代碼看起來更加清晰。
MVP模式可以分離顯示層和邏輯層,所以功能接口如何工作與功能的展示可以實現分離,MVP模式理想化地可以實現同一份邏輯代碼搭配不同的顯示界面。不過MVP不是一個結構化的模式,它只是負責顯示層而已,任何時候都可以在自己的項目結構中使用MVP模式。(不局限于Android項目開發)
因為MVP其實就是從MVC模式演化產生的,那么我們先看一下著名的MVC模式:
* ?????View:對應于布局文件
* ????? Model:業務邏輯和實體模型
* ????Controller:控制器,Android中對應于Activity
對應的交互圖如下:

雖然Android系統應用開發本身是遵循MVC開發模式的,但是我們仔細看一下View層和Activity,具體view布局文件中的數據綁定和事件處理的方法代碼都是冗余在Activity中的,所以我們經常看可以看到Activity類動不動就是少則九百行,多則上千甚至幾千行。那么現在的演化升級版本的MVP的模式又是怎么樣的呢?MVP模式會引入?Presenter層,該機型復雜完成View層和Model層的交互,那么具體MVP對應如下:
* ????? View:View通常來說是由Activity實現的,它會包含一個Presenter的引用,View要做的就只是在每次有接口調用的時候(比如按鈕點擊后)調用Presenter的方法。
* ?????? Model:業務邏輯和實體模型
* ?????Presenter:主要作為溝通View和Model的橋梁,它從Model層檢索數據后,返回給View層,但是不像MVC結構,因為它也可以決定與View層的交互操作。
數據交互圖如下:

觀察上面兩個模式的交互圖,是不是MVP模式更加清晰簡單啊!
## (三).MVC和MVP區別:
我們來具體看一下下面兩張對比,就可以看來具體區別了:

觀察上圖我們可以發現MVP模式中,View和Model的交互是通過Presenter來進行完成,這樣統一管理,邏輯會更加清晰。
## (四).MVP模式例子講解:???
4.1.具體實現功能需求:我們是用MVP模式來進行實現用戶登錄操作.
4.2.例子實例如下:?

4.3.項目代碼框架如下:




4.4.代碼具體實現:
4.4.1.Model層:Bean類(Entity),PersonBean類,然后在業務邏輯類中有登錄方法,同時把登錄成功狀態回調接口傳入進入,具體如下:
~~~
packagecom.chinaztt.fda.entity;
/**
* 當前類注釋:用戶信息實體類
* 項目名:FastDev4Android
* 包名:com.chinaztt.fda.entity
* 作者:江清清 on 15/10/27 14:13
* 郵箱:jiangqqlmj@163.com
* QQ: 781931404
* 公司:江蘇中天科技軟件技術有限公司
*/
public class PersonBean {
private String username;
private String password;
public PersonBean() {
}
public PersonBean(String username, Stringpassword) {
this.username = username;
this.password = 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;
}
@Override
public String toString() {
return "PersonBean{" +
"username='" +username + '\'' +
", password='" +password + '\'' +
'}';
}
}
~~~
~~~
public interface IPersonBiz {
void login(String username,Stringpassword,LoginRequestCallBack valueCallBack);
}
~~~
~~~
packagecom.chinaztt.fda.biz.imp;
importcom.chinaztt.fda.biz.IPersonBiz;
importcom.chinaztt.fda.biz.LoginRequestCallBack;
importcom.chinaztt.fda.entity.PersonBean;
importcom.chinaztt.fda.utils.Log;
/**
* 當前類注釋:用戶相關業務邏輯實現類
* 項目名:FastDev4Android
* 包名:com.chinaztt.fda.biz.imp
* 作者:江清清 on 15/10/27 16:33
* 郵箱:jiangqqlmj@163.com
* QQ: 781931404
* 公司:江蘇中天科技軟件技術有限公司
*/
public class PersonBizImp implements IPersonBiz{
private static final String TAG="PersonBizImp";
@Override
public void login(final String username,final String password, final LoginRequestCallBack valueCallBack) {
Log.d(TAG,"username:"+username+",password:"+password);
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(4500);
} catch (InterruptedExceptione) {
e.printStackTrace();
}
//進行開始登錄,這邊應該進行請求服務器,進行數據驗證
if(username.equals("jiangqq")&&password.equals("12345")){
valueCallBack.loginSuccess(new PersonBean(username,password));
}else{
valueCallBack.loginFailed();
}
}
}).start();
}
}
~~~
~~~
packagecom.chinaztt.fda.biz;
importcom.chinaztt.fda.entity.PersonBean;
/**
* 當前類注釋:登錄請求結果回調
* 項目名:FastDev4Android
* 包名:com.chinaztt.fda.biz
* 作者:江清清 on 15/10/27 19:50
* 郵箱:jiangqqlmj@163.com
* QQ: 781931404
* 公司:江蘇中天科技軟件技術有限公司
*/
public interface LoginRequestCallBack {
//登錄成功回調方法
void loginSuccess(PersonBean personBean);
//登錄失敗回調方法
void loginFailed();
}
~~~
4.4.2.View層:該通過Presenter與View進行交互,這邊需要定義一個接口ILoginView:
~~~
packagecom.chinaztt.fda.ui.view;
importcom.chinaztt.fda.entity.PersonBean;
/**
* 當前類注釋:登錄頁面 相關操作 功能接口
* 項目名:FastDev4Android
* 包名:com.chinaztt.fda.ui.view
* 作者:江清清 on 15/10/27 16:35
* 郵箱:jiangqqlmj@163.com
* QQ: 781931404
* 公司:江蘇中天科技軟件技術有限公司
*/
public interface ILoginView {
//獲取用戶名
String getUserName();
//獲取密碼
String getPassword();
void showSuccessInfo(PersonBeanpersonBean);
void showFailedInfo();
}
~~~
有了上面的接口之后,我們就需要寫我們的實現類Activity了,就非常簡單了
~~~
packagecom.chinaztt.fda.test;
importandroid.os.Bundle;
importandroid.view.View;
importandroid.widget.Button;
importandroid.widget.EditText;
importcom.chinaztt.fda.entity.PersonBean;
importcom.chinaztt.fda.presenter.LoginPresenter;
importcom.chinaztt.fda.ui.R;
importcom.chinaztt.fda.ui.base.BaseActivity;
importcom.chinaztt.fda.ui.view.ILoginView;
importcom.chinaztt.fda.utils.Log;
importorg.androidannotations.annotations.EActivity;
/**
* 當前類注釋:MVP開發模式實例
* 項目名:FastDev4Android
* 包名:com.chinaztt.fda.test
* 作者:江清清 on 15/10/27 13:38
* 郵箱:jiangqqlmj@163.com
* QQ: 781931404
* 公司:江蘇中天科技軟件技術有限公司
*/
@EActivity
public class MVPTestActivity extends BaseActivity implements ILoginView{
private static final String TAG="MVPTestActivity";
private EditText ed_username;
private EditText ed_password;
private Button btn_login;
private LoginPresenter mLoginPresenter;
@Override
protected void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mvp_test_layout);
ed_username=(EditText)this.findViewById(R.id.ed_username);
ed_password=(EditText)this.findViewById(R.id.ed_password);
btn_login=(Button)this.findViewById(R.id.btn_login);
mLoginPresenter=newLoginPresenter(this);
btn_login.setOnClickListener(newView.OnClickListener() {
@Override
public void onClick(View v) {
mLoginPresenter.loginSystem();
}
});
}
/**
* 進行返回用戶名信息
* @return
*/
@Override
public String getUserName() {
returned_username.getText().toString().trim();
}
/**
* 進行返回用戶密碼信息
* @return
*/
@Override
public String getPassword() {
returned_password.getText().toString().trim();
}
/**
* 登錄成功 回調
* @param personBean
*/
@Override
public void showSuccessInfo(PersonBeanpersonBean) {
Log.d(TAG,"showSuccessInfo:"+personBean.toString());
showToastMsgShort("登錄成功:"+personBean.toString());
}
/**
* 登錄失敗 回調
*/
@Override
public void showFailedInfo() {
Log.d(TAG,"showFailedInfo...");
showToastMsgShort("登錄失敗...");
}
}
~~~
最后還少一個交互橋梁Presenter:
4.4.3.Presenter層:作為Model和View之間的交互橋梁,在本例中進行執行登錄操作,然后去Model業務中執行登錄,最后把登錄結果信息返回給View層,就是這么簡單:
~~~
packagecom.chinaztt.fda.presenter;
importandroid.os.Handler;
importcom.chinaztt.fda.biz.IPersonBiz;
importcom.chinaztt.fda.biz.LoginRequestCallBack;
importcom.chinaztt.fda.biz.imp.PersonBizImp;
importcom.chinaztt.fda.entity.PersonBean;
importcom.chinaztt.fda.ui.view.ILoginView;
importcom.chinaztt.fda.utils.Log;
/**
* 當前類注釋:負責完成登錄界面View于Model(IPersonBiz)間的交互
* 項目名:FastDev4Android
* 包名:com.chinaztt.fda.presenter
* 作者:江清清 on 15/10/27 16:36
* 郵箱:jiangqqlmj@163.com
* QQ: 781931404
* 公司:江蘇中天科技軟件技術有限公司
*/
public class LoginPresenter {
private static final String TAG="LoginPresenter";
private ILoginView mLoginView;
private IPersonBiz mPersonBiz;
private Handler mHandler=new Handler();
public LoginPresenter(ILoginView view) {
mLoginView = view;
mPersonBiz = new PersonBizImp();
}
public void loginSystem(){
mPersonBiz.login(mLoginView.getUserName(), mLoginView.getPassword(), newLoginRequestCallBack() {
/**
* 登錄成功
* @param personBean
*/
@Override
public void loginSuccess(finalPersonBean personBean) {
Log.d(TAG,"登錄成功:" + personBean.toString());
mHandler.post(new Runnable() {
@Override
public void run() {
mLoginView.showSuccessInfo(personBean);
}
});
}
/**
* 登錄失敗
*/
@Override
public void loginFailed() {
Log.d(TAG,"登錄失敗...");
mHandler.post(new Runnable() {
@Override
public void run() {
mLoginView.showFailedInfo();;
}
});
}
});
}
}
~~~
到此我們的MVP模式的例子就大體完成了,看一下上面的效果演示就OK了。
我們的項目已經配置集成了MVPDemo的例子.歡迎大家去Github站點進行clone或者下載瀏覽:[https://github.com/jiangqqlmj/FastDev4Android](https://github.com/jiangqqlmj/FastDev4Android)?同時歡迎大家star和fork整個開源快速開發框架項目~
- 前言
- Android快速開發框架介紹(一)
- Android首頁圖片自動無限循環輪播Gallery+FlowIndicator(二)
- Android 列表下拉刷新組件PullToRefreshListView使用(三)
- Android 數據緩存器ACache的詳解和使用(四)
- Android崩潰異常捕捉CustomCrash,提升用戶體驗(五)
- Android實現沉浸式狀態欄(六)
- AndroidAnnnotations注入框架介紹和Android Studios基本配置(七)
- AndroidAnnnotations注入框架的工作原理(八)
- AndroidAnnnotations注入框架使用之注入組件Components(九)
- AndroidAnnnotations注入框架使用之Injection標簽詳解(十)
- AndroidAnnnotations注入框架使用之事件綁定Event Binding(十一)
- AndroidAnnnotations注入框架使用之線程處理Threading(十二)
- AndroidAnnnotations注入框架使用之第三方框架集成RoboGuice(十三)
- AndroidAnnnotations注入框架使用之第三方框架集成Otto事件總線(十四)
- AndroidAnnnotations注入框架使用之第三方框架集成OrmLite(十五)
- AndroidAnnnotations注入框架使用之最佳實踐之Adapters和lists(十六)
- AndroidAnnnotations注入框架使用之最佳實踐SharedPreferences(十七)
- Android MVP開發模式詳解(十九)
- 消息總線EventBus的基本使用(二十)
- 消息總線EventBus源碼分析以及與Otto框架對比(二十一)
- 列表頭生成帶文本或者字母的圖片開源庫TextDrawable使用和詳解(二十二)
- 重寫WebView網頁加載以及JavaScript注入詳解(二十三)
- BaseAdapterHelper的基本使用介紹,讓你擺脫狂寫一堆Adapter煩惱(二十四)
- BaseAdapterHelper詳解源碼分析,讓你擺脫狂寫一堆Adapter煩惱(二十五)
- Volley完全解析之基礎使用(二十六)
- Volley完全解析之進階最佳實踐與二次封裝(二十七)
- RecyclerView完全解析,讓你從此愛上它(二十八)
- RecyclerView完全解析之打造新版類Gallery效果(二十九)
- RecyclerView完全解析之結合AA(Android Annotations)注入框架實例(三十)
- RecyclerView完全解析之下拉刷新與上拉加載SwipeRefreshLayout(三十一)
- CardView完全解析與RecyclerView結合使用(三十二)
- 神器ViewDragHelper完全解析,媽媽再也不擔心我自定義ViewGroup滑動View操作啦~(三十三)
- 神器ViewDragHelper完全解析之詳解實現QQ5.X側滑酷炫效果(三十四)
- 實例解析之SwipeRefreshLayout+RecyclerView+CardView(三十五)
- HorizontalScrollView,Fragment,FragmentStatePagerAdapter打造網易新聞Tab及滑動頁面效果(三十六)
- Android Design支持庫TabLayout打造仿網易新聞Tab標簽效果(三十七)
- 打造QQ6.X最新版本側滑界面效果(三十八)