MVP的概念
MVP是MVC的变种,本质是对MVP设计模式的一种升级。在MVC中Activity即是View也是Controller,耦合度极高,非常不利于项目的管理。这时候MVP就应运而生了。
MVP把Activity中的UI逻辑抽象成View接口,把业务逻辑抽象成Presenter接口,Model类还是原来的Model。
在MVP模式中Activity的功能就是响应生命周期和显示界面,具体其他的工作都丢到了Presenter层中进行完成,Presenter其实是Model层和View层的桥梁。
也方便单元测试
![mvp模型](https://img-blog.csdn.net/20160808161527703)
MVP设计模式的Demo
Model层
public class User {
private String name;
private String password;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
View层
public interface ILoginView {
public void onClearText();
public void onLoginResult(Boolean result,int code);
}
public class MainActivity extends AppCompatActivity implements ILoginView, View.OnClickListener {
private EditText mName;
private EditText mPassWord;
private Button mLogin;
private Button mClear;
private ILoginPresenter loginPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
mName = (EditText) findViewById(et_name);
mPassWord = (EditText) findViewById(et_password);
mLogin = (Button) findViewById(R.id.btn_login);
mClear = (Button) findViewById(R.id.btn_clear);
mLogin.setOnClickListener(this);
mClear.setOnClickListener(this);
loginPresenter = new LoginPresenterCompl(this);
}
@Override
public void onClearText() {
mName.setText("");
mPassWord.setText("");
Toast.makeText(this, "clear", Toast.LENGTH_SHORT).show();
}
@Override
public void onLoginResult(Boolean result, int code) {
mLogin.setEnabled(true);
mClear.setEnabled(true);
if (result) {
Toast.makeText(this, "登陆成功: " + code, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "登陆失败:" + code, Toast.LENGTH_SHORT).show();
}
}
@Override
public void onClick(View v) {
int id = v.getId();
String name = mName.getText().toString();
String password = mPassWord.getText().toString();
switch (id) {
case R.id.btn_login:
loginPresenter.doLogin(name, password);
break;
case R.id.btn_clear:
loginPresenter.clear();
break;
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<EditText
android:id="@+id/et_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginTop="94dp"
android:ems="10"
android:hint="name"
android:inputType="textPersonName"/>
<EditText
android:id="@+id/et_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/et_name"
android:ems="10"
android:hint="password"
android:inputType="textPassword"/>
<Button
android:id="@+id/btn_login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:text="LOGIN"/>
<Button
android:id="@+id/btn_clear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/btn_login"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:text="CLEAR"/>
</RelativeLayout>
Presenter层
public interface ILoginPresenter {
public void clear();
public void doLogin(String name,String password);
}
public class LoginPresenterCompl implements ILoginPresenter {
private ILoginView loginView;
private User user;
public LoginPresenterCompl(ILoginView view) {
loginView = view;
user=new User();
user.setName("zhangsan");
user.setPassword("123456");
}
@Override
public void clear() {
loginView.onClearText();
}
@Override
public void doLogin(String name, String password) {
boolean result = false;
int code = 0;
if (name.equals(user.getName()) && password.equals(user.getPassword())) {
result = true;
code = 1;
} else {
result = false;
code = 0;
}
loginView.onLoginResult(result, code);
}
}
处理MVP模式造成的泄漏
由于Present和View相互持有对象,所以内存泄漏了
处理方法:
在特定的时候将view中的P层置空,那么GC就可以将他们回收了
@Override
protected void onDestroy() {
super.onDestroy();
loginPresenter=null;
}
也可以,在其中一个环节使用软引用.但这样做在内存不足时候有一定的风险;