android界一直流传着这样一种架构–MVP!What, Most Valueable Player?!NO,NO,NO! 此MVP非彼MVP,打篮球的还搞不懂android的。那么MVP架构到底是什么呢?
—MVP其实同MVC一样,是一种编程模式和思想,也许更准确地讲是一种架构。
MVC简介
开发Android的都知道MVC。
M对应Model,代表业务数据
V对应View,代表视图
C对应Controller,代表控制器。
MVC架构将视图和数据分离,在WEB领域中应用的很广泛。
用户通过界面组件进行操作,也就是View层,相应的动作会传递给控制器也就是Controller层,而Controller根据自己的业务逻辑去操作数据层也就是Model,而最终数据层的变化会同步更新到视图层。
图中也可以看出,各层之间都可以互相交互。且在平常的android开发过程中,Activity类基本担当了view和controller层两份责任,这并不符合软件设计原则的“单一职责”原则,并且随着软件功能的扩展,Activity类继承的功能会变得越来越多,动不动都几千行的代码,维护起来很麻烦,MVP架构则减轻了在Android开发中的这种问题。
MVP简介
首先,mvp架构是在mvc架构上发展而来的,它也包含三个层次:
M对应Model,代表业务数据
V对应View,代表视图,用于界面显示
P对应Presenter,代表控制层,用于连接view和model,处理业务逻辑。
从架构图中可以看出,model层与view层没有交互,两者都通过presenter层进行间接的通信。
MVP的基本思想是面向接口编程,在android开发中的基本流程如下:
1. View层定义View.interface,用来定义View的行为。一般由Activity或者是Fragment来实现这个接口,它定义了View视图的各种变化,如设置Textview,加载对话框,更新进度条等。
2. Model层定义Modle.interface,这个是用来定义数据层发生变化时的通知接口,因为Model不能直接与View交互,所以它与Presenter交互,然后再通过Presenter间接达到与View的交互。
3. Presenter翻译的意思是主持人,也就是主持场合,控制节奏的意思。在这时Presenter就负责具体的业务逻辑,请求数据,把数据送到Model,或者监听Model的数据变化,接受View层的动作,负责通过通知View层的视图变化。
接下来,用一个实例来说明MVP架构的开发流程。
实例演示
我们现在要做一个登录界面:
界面显示两个输入框,一个登录按钮。
输入框中输入“123”,“123”,点击按钮,界面显示登录进度,然后返回登录结果。
项目代码目录结构如下:
代码中定义了视图view接口以及数据model接口,以及presenter层的类LoginPresenter,还有一个接口IResultCallBack,这个接口主要是用于model层结果通知presenter层,接下来慢慢实现类中的内容。
- view层需要实现的功能:
- 登录结果显示;
- 显示登录过程进度;
- 取消登录进度显示
所以view接口需要实现的功能
public interface ILoginView {
void loginSuccess();
void showProgress();
void dismissProgre)
}
public class LoginActivity extends AppCompatActivity implements ILoginView{
private Button mLoginBtn;
private TextView mUser;
private TextView mPsw;
private LoginPresenter mLoginPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mUser = (TextView) findViewById(R.id.user);
mPsw = (TextView) findViewById(R.id.psw);
mLoginBtn = (Button) findViewById(R.id.login);
mLoginPresenter = new LoginPresenter(this);
mLoginBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mLoginPresenter.login(mUser.getText().toString(), mPsw.getText().toString());
}
});
}
@Override
public void loginSuccess() {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(LoginActivity.this,"登录成功",Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void showProgress() {
ProgressUtil.show(this,"登录中...",null,false,null);
}
@Override
public void dismissProgress() {
runOnUiThread(new Runnable() {
@Override
public void run() {
ProgressUtil.dismiss();
}
});
}
}
2.Presenter层需要实现的功能
1. 执行登录操作;
public class LoginPresenter {
private ILoginView mLoginView;
private ILoginModel mLoginModel;
public LoginPresenter(ILoginView view) {
this.mLoginView = view;
this.mLoginModel = new LoginModel();
}
public void login(String user, String psw) {
mLoginView.showProgress();
mLoginModel.login(user,psw,new IResultCallBack() {
@Override
public void onSuccess(Object o) {
mLoginView.loginSuccess();
mLoginView.dismissProgress();
}
@Override
public void onFail(Exception e) {
}
});
}
}
3.model层需要实现的功能
验证账号密码并返回登录结果
public interface ILoginModel {
void login(String user, String psw, IResultCallBack resultCallBack);
}
public class LoginModel implements ILoginModel {
@Override
public void login(String user, String psw, final IResultCallBack resultCallBack) {
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
resultCallBack.onSuccess(null);
}
}).start();
}
}
这样,简单的mvp架构就实现了。