原文:https://blog.csdn.net/uyy203/article/details/78950718
MVP架構(gòu)的概念
MVP(Model-View-Presenter)是從經(jīng)典的模式MVC演變而來的,它們的基本思想有相通的地方:Controller/Presenter負(fù)責(zé)邏輯的處理凌彬,Model提供數(shù)據(jù)东揣,View負(fù)責(zé)顯示。作為一種新的模式薄料,MVP與MVC有著一個(gè)重大的區(qū)別:在MVP中View并不直接使用Model,它們之間的通信是通過Presenter (MVC中的Controller)來進(jìn)行的泵琳,所有的交互都發(fā)生在Presenter內(nèi)部摄职,而在MVC中View會(huì)直接從Model中讀取數(shù)據(jù)而不是通過 Controller誊役。
View: 對(duì)應(yīng)于Activity,負(fù)責(zé)View的繪制以及與用戶交互
Model: 依然是業(yè)務(wù)邏輯和實(shí)體模型
Presenter: 負(fù)責(zé)完成View于Model間的交互
View不直接與Model交互谷市,而是通過與Presenter交互來與Model間接交互蛔垢。
Presenter與View的交互是通過接口來進(jìn)行的。
通常View與Presenter是一對(duì)一的迫悠,但復(fù)雜的View可能綁定多個(gè)Presenter來處理邏輯鹏漆。
MVP架構(gòu)模式的簡(jiǎn)單實(shí)踐
Version實(shí)體類
public class Version implements Serializable{
//是否有新版本
private String hasNewVersion;
//新版本名
private String versionName;
//最新版本號(hào)
private String versionCode;
public void setHasNewVersion(String hasNewVersion) {
this.hasNewVersion = hasNewVersion;
}
public String getHasNewVersion() {
return hasNewVersion;
}
public String getVersionName() {
return versionName;
}
public void setVersionName(String versionName) {
this.versionName = versionName;
}
public String getVersionCode() {
return versionCode;
}
public void setVersionCode(String versionCode) {
this.versionCode = versionCode;
}
}
主界面有兩個(gè)TextView,一個(gè)用于顯示版本名创泄,一個(gè)用于顯示版本號(hào)艺玲,還有一個(gè)按鈕,點(diǎn)擊按鈕會(huì)觸發(fā)請(qǐng)求鞠抑,代碼如下:
public class MvpActivity extends AppCompatActivity implements VersionView {
private TextView versionName;
private TextView versionCode;
private VersionPresenter mVersionPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mvp);
versionName = (TextView) findViewById(R.id.version_name);
versionCode = (TextView) findViewById(R.id.version_code);
mVersionPresenter = VersionPresenter.getInstance(this);
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mVersionPresenter.getNewVersion(getApplicationContext(), "local-url");
}
});
}
@Override
public void showVersionNameAndDesc(Version version) {
versionName.setText("最新版本名:" + version.getVersionName());
versionCode.setText("最新版本號(hào):" + version.getVersionCode());
}
@Override
public void showToast(String msg) {
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
}
}
該Activity實(shí)現(xiàn)了VersionView接口饭聚,這就是mvp中的view層,用于跟用戶交互搁拙,顯示數(shù)據(jù)秒梳。我們可以看到VersionPresenter的初始化,VersionPresenter屬于presenter層箕速,用于處理view與model層的通信酪碘,不讓view直接操作model,可見用戶點(diǎn)擊按鈕后盐茎,就通知VersionPresenter去獲取版本信息兴垦,至于如何獲取版本信息,presenter層會(huì)交給對(duì)應(yīng)的model去進(jìn)行處理庭呜,下面是VersionPresenter的代碼:
public class VersionPresenter extends IPresenter {
private static VersionPresenter mVersionPresenter;
private VersionModel mVersionModel;
private VersionView mVersionView;
private VersionPresenter(IView view){
this.mVersionView = (VersionView) view;
this.mVersionModel = new VersionModel();
}
public static VersionPresenter getInstance(VersionView view){
if (mVersionPresenter == null){
synchronized (VersionPresenter.class){
if (mVersionPresenter == null){
mVersionPresenter = new VersionPresenter(view);
}
}
}
return mVersionPresenter;
}
//獲取版本信息
public void getNewVersion(final Context context, String url){
mVersionModel.getNewVersion(url, new VersionModel.VersionCallback() {
@Override
public void onVersionCallback(final Version version) {
((Activity)context).runOnUiThread(new Runnable() {
@Override
public void run() {
mVersionView.showVersionNameAndDesc(version);
if (version.getHasNewVersion().equals("true")){
mVersionView.showToast("App有新版本,請(qǐng)更新");
}
}
});
}
});
}
}
用戶通知presenter后滑进,presenter就把view的需求通知model層,數(shù)據(jù)操作交給model層去做具體實(shí)現(xiàn)募谎,可以見到在VersionPresenter的getNewVersion方法中只是把view傳過來的參數(shù)給到model扶关,具體的網(wǎng)絡(luò)請(qǐng)求交給VersionModel去實(shí)現(xiàn),下面是VersionModel的具體實(shí)現(xiàn):
public class VersionModel implements IModel {
public interface VersionCallback {
void onVersionCallback(Version version);
}
private HttpURLConnection httpURLConnection = null;
private InputStream inputStream = null;
private BufferedReader bufferedReader = null;
public void getNewVersion(final String url, final VersionCallback versionCallback) {
new Thread(new Runnable() {
@Override
public void run() {
try {
httpURLConnection = (HttpURLConnection) new URL(url).openConnection();
httpURLConnection.connect();
inputStream = httpURLConnection.getInputStream();
bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "utf-8"));
StringBuilder stringBuilder = new StringBuilder();
String tempLine = null;
while ((tempLine = bufferedReader.readLine()) != null) {
stringBuilder.append(tempLine).append("\n");
}
String data = stringBuilder.toString();
Log.e("data", data);
JSONObject jsonObject;
jsonObject = new JSONObject(data);
Version version=new Version();
version.setHasNewVersion("has_new_version");
version.setVersionCode(jsonObject.optString("version_code"));
version.setVersionName(jsonObject.optString("version_name"));
versionCallback.onVersionCallback(version);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
bufferedReader.close();
inputStream.close();
} catch (Exception e) {
}
}
}
}).start();
}
}
VersionModel去執(zhí)行網(wǎng)絡(luò)請(qǐng)求数冬,獲取到VersonView需要的數(shù)據(jù)然后回調(diào)到VersionPresenter节槐,再由VersionPresenter通知VersonView去做UI的變化或者其他一些操作」丈矗縱觀整個(gè)過程可以發(fā)現(xiàn)铜异,view層和model層沒有一絲耦合,這就是mvp架構(gòu)模式的初衷秸架,做到了松耦合揍庄,view,model东抹,presenter每一層負(fù)責(zé)自身的工作蚂子,絕不越界沃测。