湖畔镇

Android-MVP

MVP现在已经是非常流行的Android架构

MVC

M-Model 数据模型
C-Controller 控制器,基本上就是Activity
V-View 视图,XML文件

传统的MVC存在问题:布局文件能做的事情特别少,实际上关于该布局文件中的数据绑定的操作,事件处理的代码都在Activity中,造成了Activity既像View又像Controller

MVP

M-Model 数据模型
V-View 对应于Activity,负责View的绘制以及与用户交互
P-Presenter 控制器,负责完成View与Model间的交互

MVP与MVC的显著区别是Model不与View直接交互,通过Presenter完成,Presenter与View之间的交互通过接口完成

经典实例——登录页面

Model

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public User {
private String username;
private String 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;
}
}

事务逻辑,登录功能的接口

1
2
3
4
public interface IUserBiz
{
public void login(String username, String password, OnLoginListener loginListener);
}

事务逻辑的实现类

1
2
3
4
5
6
7
8
9
public class UserBiz implements IUserBiz
{

@Override
public void login(final String username, final String password, final OnLoginListener loginListener)
{
......
}
}

View

View需要实现一个接口,该接口用来跟Presenter交互
这些接口里面操作UI元素,可以通过分析View中的UI元素知道需要哪些接口函数

1
2
3
4
5
6
7
8
9
10
11
public interface IUserLoginView
{
String getUserName();
String getPassword();
void clearUserName();
void clearPassword();
void showLoading();
void hideLoading();
void toMainActivity(User user);
void showFailedError();
}

实现的Activity或Fragment,其中要持有Presenter的引用,功能通过Presenter实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class UserLoginActivity extends ActionBarActivity implements IUserLoginView
{
private UserLoginPresenter mUserLoginPresenter = new UserLoginPresenter(this);

@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_login);

mBtnLogin = (Button) findViewById(R.id.id_btn_login);
mBtnLogin.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
mUserLoginPresenter.login();
}
});
}

......
}

Presenter

Presenter直接操作Model,通过事务逻辑实现类实现功能
Presenter持有View的引用,可以获得UI输入,并通过接口刷新UI

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public class UserLoginPresenter
{
private IUserBiz userBiz;
private IUserLoginView userLoginView;

public UserLoginPresenter(IUserLoginView userLoginView)
{
this.userLoginView = userLoginView;
this.userBiz = new UserBiz();
}

public void login()
{
userLoginView.showLoading();
userBiz.login(userLoginView.getUserName(), userLoginView.getPassword(), new OnLoginListener()
{
@Override
public void loginSuccess(final User user)
{
mHandler.post(new Runnable()
{
@Override
public void run()
{
userLoginView.toMainActivity(user);
userLoginView.hideLoading();
}
});
}

@Override
public void loginFailed()
{
//需要在UI线程执行
mHandler.post(new Runnable()
{
@Override
public void run()
{
userLoginView.showFailedError();
userLoginView.hideLoading();
}
});
}
});
}
......
}

模型中一般需要提供回调接口

1
2
3
4
5
public interface OnLoginListener
{
void loginSuccess(User user);
void loginFailed();
}

数据流

  1. Presenter通过IView接口拿到UI输入
  2. Presenter调用Model事务逻辑实现功能
  3. Model事务逻辑通过回调接口返回结果给Presenter
  4. Presenter调用IView接口刷新UI
分享