Android MVP

Android MVP_第1张图片
mvc与mvp的比较.png

比较两种架构的文章已经很多了,我不再赘述。

以一个简单的登录操作为例:

先说View

public interface BaseInterface {
    /**
     * 显示请求中dialog
     */
    public void showDownloadingDialog();
    /**
     * 隐藏请求中dialog
     */
    public void dismissDownloadingDialog();
    /**
     * 网络错误
     */
    public void showInternetError();
}

上面定义了凡是具有网络请求的界面都必备的方法。
下面是LoginActivity所特有的一些操作。

public interface ILoginView extends BaseInterface {
     /**
     * 登录成功后干啥
     */
    public void loginSuccess();
    /**
     * 登录失败后干啥
     */
    public void loginFailed();
    /**
     * 返回账号
     */
    public String getAccount();
    /**
     * 返回密码
     */
    public String getPsw();
}

接下来是LoginActivity的具体实现。

public class LoginView extends BaseActivity implements ILoginView {

    ILoginPresenter iLoginPresenter = null;

    @Bind(R.id.etAccount)
    EditText etAccount;
    @Bind(R.id.etPsw)
    EditText etPsw;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        subSetContentView(R.layout.activity_login);
        iLoginPresenter = new LoginPresenter(this);
    }

    @Override
    public void loginSuccess() {
        Toast.makeText(this, "登录成功", Toast.LENGTH_SHORT).show();
    }

    @Override
    public String getAccount() {
        return etAccount.getText().toString().trim();
    }

    @Override
    public String getPsw() {
        return etPsw.getText().toString().trim();
    }

    @Override
    public void loginFailed() {
        Toast.makeText(this, "账号或密码错误", Toast.LENGTH_SHORT).show();
    }

    @OnClick({R.id.btnLogin})
    @Override
    public void onClick(View v) {
        super.onClick(v);
        switch (v.getId()) {
            case R.id.btnLogin:
                iLoginPresenter.login();
                break;
        }
    }

细心的你也许会想,BaseInterface接口里面的三个方法去哪实现了呢,答案在BaseActivity里。

public class BaseActivity extends Activity implements OnClickListener {

    //略去其他代码

    public void showDownloadingDialog() {
        Toast.makeText(this, "showDownloadingDialog ...", Toast.LENGTH_SHORT)
                .show();
    }
    public void dismissDownloadingDialog() {
        Toast.makeText(this, "dismissDownloadingDialog ...", Toast.LENGTH_SHORT)
                .show();
    }
    public void showInternetError() {
        Toast.makeText(this, "网络错误", Toast.LENGTH_SHORT).show();
    }
}

接下来说Presenter

public interface ILoginPresenter {
    public void login();
}
public class LoginPresenter implements ILoginPresenter {

    private ILoginView iLoginView = null;
    private LoginModel loginModel = null;

    public LoginPresenter(ILoginView iLoginView) {
        this.iLoginView = iLoginView;
        this.loginModel = new LoginModel();
    }

    @Override
    public void login() {
        String account = iLoginView.getAccount();
        String psw = iLoginView.getPsw();

        iLoginView.showDownloadingDialog();

        // 1.模拟本地登录
        boolean ifSuccess = loginModel.loginLocal(account, psw);

        if (ifSuccess) {
            iLoginView.loginSuccess();
        } else {
            iLoginView.loginFailed();
        }

        // 2.模拟网络登录
        loginModel.loginInternet(account, psw, new OnLoginListener() {

            @Override
            public void loginSuccess() {
                iLoginView.dismissDownloadingDialog();
                iLoginView.loginSuccess();
            }

            @Override
            public void loginFailed() {
                iLoginView.dismissDownloadingDialog();
                iLoginView.loginFailed();
            }

            @Override
            public void internetError() {
                iLoginView.dismissDownloadingDialog();
                iLoginView.showInternetError();
            }
        });
    }

    /**
     * 用于获取用户登录结果的回调
     */
    public interface OnLoginListener {
        void loginSuccess();
        void loginFailed();
        void internetError();
    }

}

最后说Model

public class LoginModel {

    /**
     * 通过查询本地数据库验证用户名密码是否正确,未开启子线程
     */
    public boolean loginLocal(String account, String psw) {

        String temp = "1";

        if (temp.equals(account) && temp.equals(psw)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 通过网络,向服务器验证用户名密码是否合法,需要传入回调
     */
    public void loginInternet(String account, String psw,
            LoginPresenter.OnLoginListener onLoginListener) {
        //      do some internet thing
        //      if success,invoke onLoginListener.loginSuccess() and maybe need to store necessary data to local DB;
        //      if failed,invoke onLoginListener.loginFailed();
        //      if internet error,invoke onLoginListener.internetError();

    }
}

好像忘记介绍activity布局了,很简单




    

    

    

效果就是酱婶儿的

Android MVP_第2张图片
没什么好看的.png

一点体会

Activity代码是不是清爽了很多,因为业务逻辑都被剥离出去了。

什么是接口?接口就是“协议”啊。业务逻辑通常是代表了一系列或繁或简的操作,如果全部在View里面实现,会搞得代码非常难以维护,这显然是不合理的。所以,在MVP中,View只定义了这一系列操作的开端,例如,点击了登录按钮,具体业务是在presenter中实现的。可以这样做的前提是,View与Presenter之间已经签订了协议——“你需要我干什么,按照协议里商量的好的办法告诉我就行了”。

你可能感兴趣的:(Android MVP)