Android MVP模式(带实例)
目录
Google官方MVP Sample代码解读
关于Android程序的构架, 当前最流行的模式即为MVP模式, Google官方提供了Sample代码来展示这种模式的用法.
Repo地址: android-architecture.
本文为阅读官方sample代码的阅读笔记和分析.
官方Android Architecture Blueprints [beta]:
Android在如何组织和构架一个app方面提供了很大的灵活性, 但是同时这种*也可能会导致app在测试, 维护, 扩展方面变得困难.
Android Architecture Blueprints展示了可能的解决方案. 在这个项目里, 我们用各种不同的构架概念和工具实现了同一个应用(To Do App). 主要的关注点在于代码结构, 构架, 测试和维护性.
但是请记住, 用这些模式构架app的方式有很多种, 要根据你的需要, 不要把这些当做绝对的典范.
MVP模式 概念
之前有一个MVC模式: Model-View-Controller.
MVC模式 有两个主要的缺点: 首先, View持有Controller和Model的引用; 第二, 它没有把对UI逻辑的操作限制在单一的类里, 这个职能被Controller和View或者Model共享.
所以后来提出了MVP模式来克服这些缺点.
MVP(Model-View-Presenter)模式:
- Model: 数据层. 负责与网络层和数据库层的逻辑交互.
- View: UI层. 显示数据, 并向Presenter报告用户行为.
- Presenter: 从Model拿数据, 应用到UI层, 管理UI的状态, 决定要显示什么, 响应用户的行为.
MVP模式的最主要优势就是耦合降低, Presenter变为纯Java的代码逻辑, 不再与Android Framework中的类如Activity, Fragment等关联, 便于写单元测试.
来不及解释了,直接上代码
javabean 层 : User类
public class User {
private String userName;
private String password;
public User(String userName, String password) {
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;
}
}
model层:LoginModelImpl类
public class LoginModelImpl {
public void doLogin(final User user, final OnLoginListener onLoginListener){
new Thread(new Runnable() {
@Override
public void run() {
try {
sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(user.getUserName().equals("1")){
LoginInfo loginInfo= new LoginInfo();
loginInfo.setName("t001");
loginInfo.setUserid("t001");
loginInfo.setRole("tbrole3");
onLoginListener.loginSuccess(loginInfo);
}else{
onLoginListener.loginFail("login fail");
}
}
}).start();
}
public interface OnLoginListener{
void loginSuccess(LoginInfo loginInfo);
void loginFail(String fail);
}
}
LoginInfo 类 序列化
public class LoginInfo implements Parcelable {
private String userid;
private String name;
private String role;
public LoginInfo(){
}
protected LoginInfo(Parcel in) {
userid = in.readString();
name = in.readString();
role = in.readString();
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(userid);
parcel.writeString(name);
parcel.writeString(role);
}
@Override
public int describeContents() {
return 0;
}
public static final Creator<LoginInfo> CREATOR = new Creator<LoginInfo>() {
@Override
public LoginInfo createFromParcel(Parcel in) {
return new LoginInfo(in);
}
@Override
public LoginInfo[] newArray(int size) {
return new LoginInfo[size];
}
};
public String getUserid() {
return userid;
}
public void setUserid(String userid) {
this.userid = userid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
}
Presenter层:LoginPresenter类
public class LoginPresenter {
private LoginView loginView;
private LoginModelImpl loginModel;
private User user;
private Handler handler;
public LoginPresenter(LoginView loginView) {
this.loginView = loginView;
loginModel = new LoginModelImpl();
handler = new Handler();
}
public void doLogin(){
user = new User(loginView.getUserName(),loginView.getPassword());
loginView.showProgressBar();
loginModel.doLogin(user, new LoginModelImpl.OnLoginListener() {
@Override
public void loginSuccess(final LoginInfo loginInfo) {
//登录成功返回的数据进行处理
handler.post(new Runnable() {
@Override
public void run() {
loginView.hideProgressBar();
loginView.showLoginSuccessMsg(loginInfo);
}
});
}
@Override
public void loginFail(final String fail) {
handler.post(new Runnable() {
@Override
public void run() {
loginView.hideProgressBar();
loginView.showLoginFailMsg(fail);
}
});
}
});
}
}
loginView类
public interface LoginView {
String getUserName();
String getPassword();
void showProgressBar();
void hideProgressBar();
void showLoginSuccessMsg(LoginInfo loginInfo);
void showLoginFailMsg(String fail);
}
View层 :LoginActivity类
public class LoginActivity extends AppCompatActivity implements LoginView,View.OnClickListener{
private EditText etUserName;
private EditText etPassword;
private Button btnLogin;
private ProgressBar progressBar;
private LoginPresenter loginPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
initView();
}
private void initView() {
etUserName = (EditText)findViewById(R.id.et_user_name);
etPassword = (EditText)findViewById(R.id.et_password);
btnLogin = (Button) findViewById(R.id.btn_login);
progressBar = (ProgressBar) findViewById(R.id.progress_bar);
btnLogin.setOnClickListener(this);
loginPresenter = new LoginPresenter(this);
}
@Override
public void onClick(View view) {
loginPresenter.doLogin();
}
@Override
public String getUserName() {
return etUserName.getText().toString().trim();
}
@Override
public String getPassword() {
return etPassword.getText().toString().trim();
}
@Override
public void showProgressBar() {
progressBar.setVisibility(View.VISIBLE);
}
@Override
public void hideProgressBar() {
progressBar.setVisibility(View.GONE);
}
@Override
public void showLoginSuccessMsg(LoginInfo loginInfo) {
Toast.makeText(this,loginInfo.getName()+" login success",Toast.LENGTH_SHORT).show();
}
@Override
public void showLoginFailMsg(String fail) {
Toast.makeText(this,fail,Toast.LENGTH_SHORT).show();
}
}
布局:activity_login
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".LoginActivity">
<EditText
android:id="@+id/et_user_name"
android:layout_width="0dp"
android:layout_height="50dp"
android:hint="用户名"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent="0.5" />
<EditText
android:id="@+id/et_password"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginTop="20dp"
android:hint="密码"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/et_user_name"
app:layout_constraintWidth_percent="0.5" />
<Button
android:id="@+id/btn_login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:hint="登 录"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/et_password" />
<ProgressBar
android:id="@+id/progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:visibility="gone"
app:layout_constraintTop_toTopOf="parent"/>
</android.support.constraint.ConstraintLayout>
觉得你的学习有所帮助,请给自己学习的动力吧!!!
我们相会代码中
上一篇: JSP标签