一、MVP架构优缺点
优点:
1、页面与逻辑分离,降低代码间耦合度
2、逻辑代码放在Presenter中,方便做单元测试
3、代码复用
缺点:
1、由于对视图的渲染放在了Presenter中,所以视图和Presenter的交互会过于频繁。如果Presenter过多地渲染了视图,往往会使得它与特定的视图的联系过于紧密。一旦视图需要变更,那么Presenter也需要变更了。
2、会增加很多接口及类文件,增大应用体积
二、Android中使用MVP
M->Model ->数据模型层(一般为javaBean或者获取数据的模块类)
V->View->视图层(一般为Activity类)
P->Presenter->逻辑处理层(一般实现具体业务逻辑或者调用Model实现承上启下)
三、架构实现
1、BaseView类
public abstract class BaseView<P extends BasePresenter> extends ComponentActivity {
protected P p;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
p = getPresenter();
p.bind(this);
}
//通过子类获取Presenter
protected abstract P getPresenter();
@Override
protected void onDestroy() {
super.onDestroy();
p.unBind();
}
}
2、BasePresenter类
public class BasePresenter<V extends BaseView> {
//Presenter持有View的弱引用
private WeakReference<V> weakReference;
protected V getView() {
if (weakReference != null) {
return weakReference.get();
}
return null;
}
public void bind(V v) {
weakReference = new WeakReference<>(v);
}
//若有网络请求等耗时操作,要先取消,不然在回调View方法时会造成空指针
public void unBind() {
if (weakReference != null) {
weakReference.clear();
weakReference = null;
System.gc();
}
}
}
3、LoginContract类
public interface LoginContract {
interface View {
void loginSuccess(LoginEntity loginEntity);
void loginErr(String msg);
}
interface Presenter {
void login(String name, String pwd);
}
}
4、LoginPresenter类
public class LoginPresenter extends BasePresenter<LoginActivity> implements LoginContract.Presenter {
@Override
public void login(String name, String pwd) {
if ("user".equals(name) && "pwd".equals(pwd)) {
new Thread(new Runnable() {
@Override
public void run() {
Log.e("TAG===>", "开始休眠");
SystemClock.sleep(15000);
Log.e("TAG===>", "休眠结束");
LoginEntity loginEntity = new LoginEntity();
getView().loginSuccess(loginEntity);
}
}).start();
} else {
getView().loginErr("登录失败");
}
}
}
5、LoginActivity类
public class LoginActivity extends BaseView<LoginPresenter> implements LoginContract.View {
private EditText nameEt;
private EditText pwdEt;
private Button loginBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
initView();
initListener();
}
private void initView() {
nameEt = findViewById(R.id.name_et);
pwdEt = findViewById(R.id.pwd_et);
loginBtn = findViewById(R.id.login_btn);
}
private void initListener() {
loginBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String name = nameEt.getText().toString();
String pwd = pwdEt.getText().toString();
p.login(name, pwd);
}
});
}
@Override
protected LoginPresenter getPresenter() {
return new LoginPresenter();
}
@Override
public void loginSuccess(LoginEntity loginEntity) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(LoginActivity.this, "登录成功", Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void loginErr(String msg) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
}
}