MVP再理解2
基类(父类)与接口
- 抽取父类
2.项目结构
3.BaseView
//View层基类
public abstract class BaseView<P extends BasePresenter,CONTRACT> extends Activity {
protected P p;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//弱引用
p=getPresenter();
//绑定
p.bindView(this);
}
//让P层做什么需求
public abstract CONTRACT getContract();
//从子类中获取具体的契约
public abstract P getPresenter();
//如果Presenter层出现异常,需要告知View层
public void error(Exception e){}
@Override
protected void onDestroy() {
super.onDestroy();
//解除绑定
p.unBindView();
}
}
4.BasePresenter
public abstract class BasePresenter<M extends BaseModel,V extends BaseView,CONTRACT> {
protected M m;
private WeakReference<V> vWeakReference;
public BasePresenter() {
m=getModel();
}
public void bindView(V v){
vWeakReference=new WeakReference<>(v);
}
public void unBindView() {
if (vWeakReference != null){
vWeakReference.clear();
vWeakReference=null;
System.gc();
}
}
public V getView(){
if (vWeakReference != null){
return vWeakReference.get();
}
return null;
}
public abstract CONTRACT getContract();
public abstract M getModel();
}
5.BaseModel
//接收到P层交给它的需求
public abstract class BaseModel<P extends BasePresenter,CONTRACT>{
protected P p;
public BaseModel(P p) {
this.p = p;
}
public abstract CONTRACT getContract();
}
6.封装的接口
//将Model层、view层、presenter层协商的共同业务,封装成接口
public interface LoginContract {
interface Model{
// Model层子类完成方法的具体实现 ...............2
void executeLogin(String name,String pwd) throws Exception;
}
interface View<T extends BaseEntity>{
//真实的项目中,请求结果往往是以JavaBean ...............4
void handlerResult(T t);
}
interface Presenter<T extends BaseEntity>{
//登录请求(接收到View层指令、可以自己做,也可以让Model层去执行)...............1
void requestLogin(String name,String pwd);
//结果响应(接收到Model层处理的结果,通知View层刷新) ...............3
void responseResult(T t);
}
}
实现类
1.LoginView
public class LoginActivity extends BaseView<LoginPresenter, LoginContract.View> {
private EditText nameEt,pwdEt;
private Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
nameEt=findViewById(R.id.et_name);
pwdEt=findViewById(R.id.et_pwd);
btn=findViewById(R.id.bt_login);
}
@Override
public LoginContract.View getContract() {
return new LoginContract.View<UserInfo>() {
@Override
public void handlerResult(UserInfo userInfo) {
if (userInfo!=null){
Toast.makeText(LoginActivity.this, userInfo.toString(), Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(LoginActivity.this, "登录失败!", Toast.LENGTH_SHORT).show();
}
}
};
}
@Override
public LoginPresenter getPresenter() {
return new LoginPresenter();
}
//点击事件
public void doLoginAction(View view) {
String name = nameEt.getText().toString();
String pwd = pwdEt.getText().toString();
p.getContract().requestLogin(name,pwd);
}
}
2.LoginPresenter
public class LoginPresenter extends BasePresenter<LoginModel, LoginActivity,LoginContract.Presenter> {
@Override
public LoginContract.Presenter getContract() {
return new LoginContract.Presenter<UserInfo>() {
@Override
public void requestLogin(String name, String pwd) {
try {
m.getContract().executeLogin(name,pwd);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void responseResult(UserInfo userInfo) {
getView().getContract().handlerResult(userInfo);
}
};
}
@Override
public LoginModel getModel() {
return new LoginModel(this);
}
}
3.LoginModel
public class LoginModel extends BaseModel<LoginPresenter,LoginContract.Model> {
public LoginModel(LoginPresenter loginPresenter) {
super(loginPresenter);
}
@Override
public LoginContract.Model getContract() {
return new LoginContract.Model() {
@Override
public void executeLogin(String name, String pwd) throws Exception {
if ("admin".equalsIgnoreCase(name) && "123456".equalsIgnoreCase(pwd)){
p.getContract().responseResult(new UserInfo("成都","陈老师"));
}else {
p.getContract().responseResult(null);
}
}
};
}
}
运行效果
MVP的项目就这样搭建好了,接下来继续学习MVVM模式,分析MVVM与MVP的区别。