Android MVP模式實戰(zhàn)教程
一、什么是MVP
在網(wǎng)上找了些資料,整理如下:
MVP是模型(Model)、視圖(View)、主持人(Presenter)的縮寫,分別代表項目中3個不同的模塊。
模型(Model):負責處理數(shù)據(jù)的加載或者存儲,比如從網(wǎng)絡或本地數(shù)據(jù)庫獲取數(shù)據(jù)等;
視圖(View):負責界面數(shù)據(jù)的展示,與用戶進行交互;
主持人(Presenter):相當于協(xié)調(diào)者,是模型與視圖之間的橋梁,將模型與視圖分離開來。
如下圖所示,View與Model并不直接交互,而是使用Presenter作為View與Model之間的橋梁。其中Presenter中同時持有Viwe層以及Model層的Interface的引用,而View層持有Presenter層Interface的引用。當View層某個界面需要展示某些數(shù)據(jù)的時候,首先會調(diào)用Presenter層的某個接口,然后Presenter層會調(diào)用Model層請求數(shù)據(jù),當Model層數(shù)據(jù)加載成功之后會調(diào)用Presenter層的回調(diào)方法通知Presenter層數(shù)據(jù)加載完畢,最后Presenter層再調(diào)用View層的接口將加載后的數(shù)據(jù)展示給用戶。這就是MVP模式的整個核心過程。

在MVP模式里通常包含4個要素:
(1)View:負責繪制UI元素、與用戶進行交互(在Android中體現(xiàn)為Activity);
(2)View interface:需要View實現(xiàn)的接口,View通過View interface與Presenter進行交互,降低耦合,方便進行單元測試;
(3)Model:負責存儲、檢索、操縱數(shù)據(jù)(有時也實現(xiàn)一個Model interface用來降低耦合);
(4)Presenter:作為View與Model交互的中間紐帶,處理與用戶交互的負責邏輯。

二、MVP模式的使用

上面一張簡單的MVP模式的UML圖,從圖中可以看出,使用MVP,至少需要經(jīng)歷以下步驟:
1.創(chuàng)建IPresenter接口,把所有業(yè)務邏輯的接口都放在這里,并創(chuàng)建它的實現(xiàn)PresenterCompl(在這里可以方便地查看業(yè)務功能,由于接口可以有多種實現(xiàn)所以也方便寫單元測試)
2.創(chuàng)建IView接口,把所有視圖邏輯的接口都放在這里,其實現(xiàn)類是當前的Activity/Fragment
3.由UML圖可以看出,Activity里包含了一個IPresenter,而PresenterCompl里又包含了一個IView并且依賴了Model。Activity里只保留對IPresenter的調(diào)用,其它工作全部留到PresenterCompl中實現(xiàn)
4.Model并不是必須有的,但是一定會有View和Presenter
三、一個簡單的MVP示例
實現(xiàn)一個簡單的用戶登錄
效果如下:

先來看看java文件的目錄結構:

1.Baen包
UserBean
package com.example.mvpe.bean;
/**
* Created by fendo on 2017/4/29.
*/
public class UserBean {
private String username;
private String userpwd;
public UserBean() {
}
public UserBean(String username, String userpwd) {
this.username = username;
this.userpwd = userpwd;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getUserpwd() {
return userpwd;
}
public void setUserpwd(String userpwd) {
this.userpwd = userpwd;
}
}
2.Model包
IUserModel類
package com.example.mvpe.model;
import com.example.mvpe.bean.UserBean;
/**
* Created by fendo on 2017/4/29.
*/
public interface IUserModel {
void setSid(int cid);
UserBean load(int sid);
void setUsername(String username);
void setUserpwd(String userpwd);
}
UserModelimp類
package com.example.mvpe.model;
import android.provider.Settings;
import android.util.Log;
import android.util.SparseArray;
import com.example.mvpe.bean.UserBean;
/**
* Created by fendo on 2017/4/29.
*/
public class UserModelimp implements IUserModel{
private static final String ACTIVITY_TAG="UserModelimp";
private String username;
private String userpwd;
private int sid;
private SparseArray<UserBean> su=new SparseArray<UserBean>();
@Override
public void setSid(int cid) {
sid=cid;
}
@Override
public UserBean load(int sidy) {
sid=sidy;
UserBean ub=su.get(sid,new UserBean("not found",
"not found"));
return ub;
}
@Override
public void setUsername(String usernamey) {
username=usernamey;
}
@Override
public void setUserpwd(String userpwdy) {
userpwd=userpwdy;
UserBean usb=new UserBean(username,userpwd);
System.out.print(username+"----"+userpwd+"----"+sid);
Log.d(UserModelimp.ACTIVITY_TAG, "Start_OK"+username+"----"+userpwd+"----"+sid);
su.append(sid,usb);
}
}
3.persenter包
UserPersenter類
package com.example.mvpe.presenter;
import android.util.Log;
import android.view.View;
import com.example.mvpe.bean.UserBean;
import com.example.mvpe.model.IUserModel;
import com.example.mvpe.model.UserModelimp;
import com.example.mvpe.view.IUserView;
/**
* Created by fendo on 2017/4/29.
*/
public class UserPersenter {
private static final String ACTIVITY_TAG="UserPersenter";
private IUserView iUserView;
private IUserModel iUserModel;
public UserPersenter(IUserView view){
iUserView=view;
iUserModel=new UserModelimp();
}
public void saveuser(int sid,String username,String userpwd){
iUserModel.setSid(sid);
iUserModel.setUsername(username);
iUserModel.setUserpwd(userpwd);
}
public void loaduser(int sid){
UserBean usb=iUserModel.load(sid);
Log.d(ACTIVITY_TAG, "loaduser: "+usb.getUsername());
iUserView.setUsername(usb.getUsername());
iUserView.setUserpwd(usb.getUserpwd());
}
}
4.view包
IUserView類
package com.example.mvpe.view;
import com.example.mvpe.bean.UserBean;
/**
* Created by fendo on 2017/4/29.
*/
public interface IUserView {
int getID();
void setUsername(String username);
void setUserpwd(String userpwd);
String getUserpwd();
String getUsername();
}
UserActivity類
package com.example.mvpe.view;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import com.example.mvpe.R;
import com.example.mvpe.presenter.UserPersenter;
import android.view.View.OnClickListener;
import android.widget.Toast;
/**
* Created by fendo on 2017/4/29.
*/
public class UserActivity extends Activity implements OnClickListener,IUserView{
private EditText userid;
private EditText username;
private EditText userpwd;
private Button read;
private Button write;
private UserPersenter usp;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
usp=new UserPersenter(this);
setContentView(R.layout.activity_main);
findviewbyid();
read.setOnClickListener(this);
write.setOnClickListener(this);
}
public void findviewbyid(){
userid= (EditText) findViewById(R.id.userid);
username= (EditText) findViewById(R.id.usertext);
userpwd= (EditText) findViewById(R.id.userpwd);
read= (Button) findViewById(R.id.read);
write= (Button) findViewById(R.id.write);
}
@Override
public int getID() {
return Integer.parseInt(userid.getText().toString());
}
@Override
public void setUsername(String usernamcc) {
username.setText(usernamcc);
}
@Override
public void setUserpwd(String userpw) {
userpwd.setText(userpw);
}
@Override
public String getUserpwd() {
return userpwd.getText().toString();
}
@Override
public String getUsername() {
return username.getText().toString();
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.read :
usp.loaduser(getID());
Toast.makeText(getApplicationContext(), "點擊了讀"+getID(), Toast.LENGTH_SHORT).show();
break;
case R.id.write:
usp.saveuser(getID(),getUsername(),getUserpwd());
Toast.makeText(getApplicationContext(), "點擊了存"+getID()+"--"+getUsername()+"--"+getUserpwd(), Toast.LENGTH_SHORT).show();
break;
}
}
}
可以看到View只負責處理與用戶進行交互,并把數(shù)據(jù)相關的邏輯操作都扔給了Presenter去做。而Presenter調(diào)用Model處理完數(shù)據(jù)之后,再通過IUserView更新View顯示的信息。
下載:源碼
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Android在類微信程序中實現(xiàn)藍牙聊天功能的示例代碼
這篇文章主要介紹了Android在類微信程序中實現(xiàn)藍牙聊天功能,本文通過實例代碼給大家介紹的非常想詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-06-06
Android開發(fā)學習之WallPaper設置壁紙詳細介紹與實例
這篇文章主要介紹了Android開發(fā)學習之WallPaper設置壁紙詳細介紹與實例,有需要的朋友可以參考一下2013-12-12
Android中定時執(zhí)行任務的3種實現(xiàn)方法(推薦)
下面小編就為大家?guī)硪黄狝ndroid中定時執(zhí)行任務的3種實現(xiàn)方法(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-11-11
Android Activity與Fragment之間的跳轉實例詳解
這篇文章主要介紹了Android Activity與Fragment之間的跳轉實例詳解的相關資料,需要的朋友可以參考下2017-02-02
Android BadTokenException異常解決案例詳解
這篇文章主要介紹了Android BadTokenException異常詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2021-08-08

