Android那点事-系列之(三)MVP模式在Android中的应用

大家好,我是Bin,今天为大家分享一下MVP模式在Android中的应用。目前有很多Android开发人员把复杂的业务逻辑和UI显示都写在了Activity里面,这种情况的缺点有很多,比如不方便单元测试;Activity太过臃肿;遇到需求更改的时候,Activity代码要做大量更改,代码复用性极低等。那么,如果在Android开发过程中,你巧用MVP模式,这些问题都会挥之而去。
你可能没听过MVP,没关系,MVC你总该知道吧。那么到底什么是MVP模式呢?它和MVC又有怎样的区别和联系呢?下面请看图:
MVP与MVC
MVP与MVC相同点在于:Controller/Presenter处理逻辑,Model提供数据,View负责显示。MVP与MVC最大的不同在于:在MVP中View并不直接访问Model,它们之间的通信是通过Presenter来进行的,所有的交互都发生在Presenter内部,而在MVC中View会从Model中读取数据而不是通过Controller。在MVC里,View是可以直接访问Model。
在MVP里,Presenter完全把Model和View进行了分离,主要的程序逻辑在Presenter里实现。而且,Presenter与具体的View是没有直接关联的,而是通过定义好的接口进行交互,从而使得在变更View时候可以保持Presenter的不变,即重用! 不仅如此,我们还可以编写测试用的View,模拟用户的各种操作,从而实现对Presenter的测试。
MVP的优点:
1、模型与视图完全分离,我们可以修改视图而不影响模型
2、可以更高效地使用模型,因为所有的交互都发生在Presenter内部
3、我们可以将一个Presenter用于多个视图,而不需要改变Presenter的逻辑。这个特性很关键,因为视图的变化要比模型的变化频繁的多。
4、把逻辑放在Presenter中,就可以脱离用户接口来进行单元测试

说了这么多关于MVP的东西,下面我将给出MVP模式在Android中应用的代码。
需求:
MVP模式实现的一个简单的登录Demo。用户输入用户名和密码,点击登录按钮,显示ProgressBar,进行登录,如果用户名,或密码为空,给出提示;否则登录成功,ProgressBar消失,跳转到MainActivity。
项目目录结构
先看M层定义的接口:

package com.mobile.mvp.models;

import com.mobile.mvp.models.listenners.OnLoginFinishedListener;

public interface LoginInteractor {
    public void login(String username, String password, OnLoginFinishedListener listener);
}

再看M层接口的实现:

package com.mobile.mvp.presenters;


import com.mobile.mvp.models.LoginInteractor;
import com.mobile.mvp.models.LoginInteractorImpl;
import com.mobile.mvp.models.listenners.OnLoginFinishedListener;
import com.mobile.mvp.views.LoginView;

public class LoginPresenterImpl implements LoginPresenter, OnLoginFinishedListener {

    private LoginView loginView;
    private LoginInteractor loginInteractor;

    public LoginPresenterImpl(LoginView loginView) {
        this.loginView = loginView;
        this.loginInteractor = new LoginInteractorImpl();
    }

    @Override
    public void validateCredentials(String username, String password) {
        loginView.showProgress();
        loginInteractor.login(username, password, this);
    }

    @Override
    public void onUsernameError() {
        loginView.setUsernameError();
        loginView.hideProgress();
    }

    @Override
    public void onPasswordError() {
        loginView.setPasswordError();
        loginView.hideProgress();
    }

    @Override
    public void onSuccess() {
        loginView.navigateToHome();
    }
}

接着看V层接口:

package com.mobile.mvp.views;

public interface LoginView {
    public void showProgress();

    public void hideProgress();

    public void setUsernameError();

    public void setPasswordError();

    public void navigateToHome();
}

V层实现:

package com.mobile.mvp.views;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;

import com.mobile.mvp.R;
import com.mobile.mvp.presenters.LoginPresenter;
import com.mobile.mvp.presenters.LoginPresenterImpl;


public class LoginActivity extends Activity implements View.OnClickListener, LoginView {
    private EditText et_name, et_pwd;
    private Button btn_login;
    private ProgressBar progress;
    private LoginPresenter presenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        initView();
        btn_login.setOnClickListener(this);
        presenter = new LoginPresenterImpl(this);
    }

    private void initView() {
        et_name = (EditText) findViewById(R.id.name);
        et_pwd = (EditText) findViewById(R.id.pwd);
        btn_login = (Button) findViewById(R.id.login);
        progress = (ProgressBar) findViewById(R.id.progress);

    }


    @Override
    public void onClick(View v) {
        presenter.validateCredentials(et_name.getText().toString(), et_pwd.getText().toString());
    }

    @Override
    public void showProgress() {
        progress.setVisibility(View.VISIBLE);
    }

    @Override
    public void hideProgress() {
        progress.setVisibility(View.GONE);
    }

    @Override
    public void setUsernameError() {
        et_name.setError("用户名为空");
    }

    @Override
    public void setPasswordError() {
        et_pwd.setError("密码为空");
    }

    @Override
    public void navigateToHome() {
        startActivity(new Intent(this,MainActivity.class));
        finish();
    }
}

最后我们看看P层接口:

package com.mobile.mvp.presenters;

public interface LoginPresenter {
    public void validateCredentials(String username, String password);
}

P层实现:

package com.mobile.mvp.presenters;

import com.mobile.mvp.models.LoginInteractor;
import com.mobile.mvp.models.LoginInteractorImpl;
import com.mobile.mvp.models.listenners.OnLoginFinishedListener;
import com.mobile.mvp.views.LoginView;

public class LoginPresenterImpl implements LoginPresenter, OnLoginFinishedListener {

    private LoginView loginView;
    private LoginInteractor loginInteractor;

    public LoginPresenterImpl(LoginView loginView) {
        this.loginView = loginView;
        this.loginInteractor = new LoginInteractorImpl();
    }

    @Override
    public void validateCredentials(String username, String password) {
        loginView.showProgress();
        loginInteractor.login(username, password, this);
    }

    @Override
    public void onUsernameError() {
        loginView.setUsernameError();
        loginView.hideProgress();
    }

    @Override
    public void onPasswordError() {
        loginView.setPasswordError();
        loginView.hideProgress();
    }

    @Override
    public void onSuccess() {
        loginView.navigateToHome();
    }
}

以上就是MVP模式在Android中的应用。

源代码下载地址

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值