Android MVP初探
最近Android MVP非常火,特地研究了一翻,至于为什么火,自行百度google
我比较喜欢的两点是:
- 业务逻辑与View和Model分离,需求变更的时候修改起来简单
- 方便单元测试
未使用MVP程序是这样的
![](https://img.haomeiwen.com/i2562009/b3b7e5504c8b8bab.png)
使用MVP后是这样的
![](https://img.haomeiwen.com/i2562009/d09c98d10a4543ab.png)
那么现在开始用MVP来做一个简单的登录页面:
1. 写接口
- Model层接口
public interface IUserModel {
/**
* 登录
*
* @param username 用户名
* @param password 密码
* @param callback 回调
*/
void login(String username, String password, Callback callback);
}
IUserModel接口就一个login方法,参数为用户名,密码以及回调
- Presenter层接口
public interface ILoginPresenter {
/**
* 登录
*/
void login();
}
ILoginPresenter接口就一个login,不需要参数,描述登录这个行为
- View层接口
public interface ILoginView {
/**
* 从UI中获取用户输入的用户名
*
* @return
*/
String getUsername();
/**
* 从UI中获取用户输入的密码
*
* @return
*/
String getPassword();
/**
* 显示加loading
*
* @param msg
*/
void showLoading(String msg);
/**
* 取消loading显示
*/
void hideLoading();
/**
* 显示结果
*
* @param result
*/
void showResult(String result);
}
ILoginView方法分两部份:
一部份是给Presenter提供数据的(View->Presenter)
getUsername
getPassword
另一部份是从Presenter接收数据用来显示的(Presenter->View)
showLoading
hideLoading
showResult
说白了就是数据交互
2. 实现接口
- Model层实现
public class UserModel implements IUserModel {
Handler handler = new Handler();
/**
* 登录
*
* @param username 用户名
* @param password 密码
* @param callback 回调
*/
@Override
public void login(final String username, final String password, final Callback callback) {
handler.postDelayed(new Runnable() {//延时200ms回调,模拟网络请求
@Override
public void run() {
if ("huangx".equals(username) && "123456".equals(password)) {
callback.onSuccess();
} else {
callback.onFailure("用户名或密码错误");
}
}
}, 2000);
}
}
UserModel 是IUserModel 的实现,正常情况就里就是调服务器登录接口,我们Demo这里就用延时操作来模拟网络请求。这里对用户名密码做了一个判断,如果用户名为huangx密码为123456就返回登录成功,否则返回“用户名或密码错误”
- Presenter层实现
public class LoginPresenter implements ILoginPresenter {
private ILoginView loginView;
private UserModel userModel;
public LoginPresenter(ILoginView loginView, UserModel userModel) {
this.loginView = loginView;
this.userModel = userModel;
}
/**
* 登录
*/
@Override
public void login() {
loginView.showLoading("登录中...");
userModel.login(loginView.getUsername(), loginView.getPassword(), new Callback() {
@Override
public void onSuccess() {
loginView.hideLoading();
loginView.showResult("登录成功");
}
@Override
public void onFailure(String errorMsg) {
loginView.hideLoading();
loginView.showResult(errorMsg);
}
});
}
}
LoginPresenter 是ILoginPresenter 的实现,也是MVP中最关键的一个角色,主要的业务逻辑都放在这里,起到连接Model层和View层的作用,从构造方法可以看出,它需要传入ILoginView和IUserModel的实例。
在login方法被调用时,LoginPresenter会从loginView获取到用户输入的用户名和密码,
并以此为参数调用userModel的login方法,
然后通过回调把结果返回给loginView
- View层实现
public class LoginActivity extends AppCompatActivity implements ILoginView, View.OnClickListener {
private EditText username;
private EditText password;
private ProgressDialog progressDialog;
private LoginPresenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
username = (EditText) findViewById(R.id.username);
password = (EditText) findViewById(R.id.password);
findViewById(R.id.login).setOnClickListener(this);
progressDialog = new ProgressDialog(this);
presenter = new LoginPresenter(this, new UserModel());
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.login:
presenter.login();
break;
}
}
/**
* 从UI中获取用户输入的用户名
*
* @return
*/
@Override
public String getUsername() {
return username.getText().toString().trim();
}
/**
* 从UI中获取用户输入的密码
*
* @return
*/
@Override
public String getPassword() {
return password.getText().toString().trim();
}
/**
* 显示加loading
*
* @param msg
*/
@Override
public void showLoading(String msg) {
progressDialog.setMessage(msg);
if (!progressDialog.isShowing()) {
progressDialog.show();
}
}
/**
* 取消loading显示
*/
@Override
public void hideLoading() {
if (progressDialog.isShowing()) {
progressDialog.dismiss();
}
}
/**
* 显示结果
*
* @param result
*/
@Override
public void showResult(String result) {
Toast.makeText(LoginActivity.this, result, Toast.LENGTH_SHORT).show();
}
}
LoginActivity 是ILoginView的实现,让LoginPresenter 可以从这里获取到用户名和密码,并用Toast显示登录给果。点击登录按钮的时候调用LoginPresenter 的login方法角色登录动作。
至此就实现了一个最简单的MVP。代码在这里
下一篇:Android MVP进阶