美文网首页
Android开发之MVP模式

Android开发之MVP模式

作者: ruancw | 来源:发表于2018-06-08 15:40 被阅读21次

    前言:Android开发中有很多的设计模式,MVP模式无疑是现在最流行的模式之一。MVP模式有效的降低了项目的复杂性及耦合性,view与model间完全解耦,通过presenter作为中间的连接纽带,降低了view的复杂性及view与model耦合程度,使的项目逻辑更加清晰,方便后期的修改与维护。

    MVP:Model--View--Presenter

    model:用于数据的处理,如请求网络数据等

    view:用于将presenter传递的数据在UI中展示

    presenter:将model获取的数据传递给view,是view与model联系的中间桥梁

    注:文中有用到Retrofit2+Rxjava2+Okhttp3实现网络数据请求相关的知识,这一篇文章 Android网络请求Retrofit2+Rxjava2+Okhttp3的简单封装中有详细介绍。

    1.Model

    (1)定义model基类接口

    /**  
    * Created by ruancw on 2018/5/22. 
    * model接口基类 
    */   
    public interface IBaseModel {
        //获取Rxjava的disposable
        <T>Disposable getObservable(Observable<HttpResponse<T>> observable, String tag);
        //网络请求接口回调
        interface IOnRequestListener<T>{
            void onRequestSuccess(HttpResponse<T> tHttpResponse, String tag);
             void onRequestFail(Throwable throwable);
        }
    }
    

    (2)定义model实现类

    /**  
    * Created by ruancw on 2018/5/22. 
    * 通用model实现类 
    */   
    public class CommonModelImpl implements IBaseModel {
        private IOnRequestListener onRequestListener;   
        public CommonModelImpl(IOnRequestListener onRequestListener) {
            this.onRequestListener = onRequestListener;
        }
    
        @Override
        public <T> Disposable getObservable(Observable<HttpResponse<T>> observable, String tag) {
            return DisposableUtils.getDisposable(observable,tag,onRequestListener);
        }
    }
    

    2.View

    定义view接口类

    /**  
    * Created by ruancw on 2018/5/22. 
    * view基类接口 
    */   
    public interface IBaseView {
        //显示默认的进度框
        void showProgress();
        //显示可设置提示信息的进度框
        void showProgress(String message);
        //隐藏进度框
        void hideProgress();
        //网络请求数据成功后返回数据的方法
        void onSuccess(HttpResponse httpResponse, String tag);
        //网络请求失败的方法
        void onFailed(Throwable throwable); 
    }
    

    3.Presenter

    (1)定义presenter的基类

    /**  
    * Created by ruancw on 2018/5/22. 
    * presenter基类 
    */   
    public class BasePresenter implements IBaseModel.IOnRequestListener {
        //view接口
        protected IBaseView mView;
        //model接口实现类
        protected CommonModelImpl mModel;
        //Rxjava中的类
        private CompositeDisposable mCompositeDisposable;    
        /**  
        * 绑定view 
        * @param mView   
        */   
        public void attach(IBaseView mView){
            this.mView=mView;
            mModel=new CommonModelImpl(this);
        }
    
        /**  
        * 解绑view 
        */  
        public void detach(){
            if (mView!=null){
                mView=null;
            }
        }
    
        /**  
        * 反注册rxjava 
        */  
        public void unSubscribe(){
            if (mCompositeDisposable != null) {
                mCompositeDisposable.dispose();
            }
        }
    
        /**  
        * 注册rxjava 
        * @param disposable   
        */   
        public void addSubscription(Disposable disposable) {
            //rxjava进行注册
            if (mCompositeDisposable == null) {
                mCompositeDisposable= new CompositeDisposable();
            }
            mCompositeDisposable.add(disposable);
        }
    
        @Override
         public void onRequestSuccess(HttpResponse httpResponse, String tag) {
            if (mView!=null){
                mView.hideProgress();
                mView.onSuccess(httpResponse,tag);
            }
        }
    
        @Override
         public void onRequestFail(Throwable throwable) {
            if (mView!=null){
                mView.hideProgress();
                mView.onFailed(throwable);
            }
        }
    }
    

    (2)继承基类BasePresenter(以登录为例)

    /**  
    * Created by ruancw on 2018/5/23. 
    * 登录的presenter实现类 
    */   
    public class LoginPresenterImpl extends BasePresenter {
        public void login(String url, LinkedHashMap<String, String> paramsMap,String tag){
            mView.showProgress("正在登录");
            addSubscription(mModel.getObservable(HttpApiService.getInstance().getRemoteData(url,paramsMap),tag));
        }
    }
    

    注:直接定义的LoginPresenter的实现类,没有定义ILoginPresenter接口

    4.模块中使用

    (1)定义Activity基类

    public abstract class BaseMvpActivity<B extends BasePresenter> extends BaseActivity {
    
        public B mPresenter;    
        @Override
        protected void beforeSetContentView() {
            mPresenter=initPresenter();
            mPresenter.attach(this);
        }
    
        protected abstract B initPresenter();    
        @Override
        protected void onDestroy() {
            mPresenter.detach();
            //mPresenter.unSubscribe();
            super.onDestroy();
        }
    }
    

    (2)LoginActivity继承BaseMvpActivity

    public class LoginActivity extends BaseMvpActivity<LoginPresenterImpl> {
        @BindView(R.id.btn_login)
        Button btnLogin;
        @BindView(R.id.et_account)
        ClearEditText etAccount;
        @BindView(R.id.et_password)
        PasswordView etPassword;
        private int userType=1;
        private UserBean userBean;
        private boolean autoLogin;      @Override
        protected boolean hasHeadTitle() {
            return false;
        }
    
        @Override
        protected LoginPresenterImpl initPresenter() {
            return new LoginPresenterImpl();
        }  
    
        @Override
        protected int getLayoutId() {
            return R.layout.activity_login;
        }
    
        @Override
        protected void initView() {
            //获取上一次填写的用手机号与密码
            userBean=SharePreferencesUtil.getInstance().getUserBean();
            if (this.getIntent() != null && this.getIntent().getExtras() != null && this.getIntent().getExtras().containsKey("username")) {
                String username = this.getIntent().getExtras().getString("username");
                etAccount.setText(username);
            } else {
                if (userBean != null) {
                    etAccount.setText(userBean.getAccount());
                    etPassword.setContent(userBean.getPassword());
                }
            }
            //判断是否是自动登录
            autoLogin=SharePreferencesUtil.getInstance().getBoolean("AUTO_LOGIN");
            if (autoLogin){
                //自动登录
                login();
            }
        }
    
        /**  
        * 登录的方法 
        */  
        private void login() {
            etPassword.clearFocus();
            //系统的输入管理器
            InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.showSoftInput(etPassword, InputMethodManager.SHOW_FORCED);
            imm.hideSoftInputFromWindow(etPassword.getWindowToken(), 0);
           if (TextUtils.isEmpty(etAccount.getText().toString().trim())) {
                UIUtil.toast("手机号不能为空");
           } else if (TextUtils.isEmpty(etPassword.getContent().trim())) {
                UIUtil.toast("密码不能为空");
           } else {
                LinkedHashMap<String, String> paramsMap = new LinkedHashMap<>();
                paramsMap.put("loginName", etAccount.getText().toString().trim());
                paramsMap.put("password", etPassword.getContent().trim());
                paramsMap.put("userType", userType + "");
                mPresenter.login(ApiConstant.LOGIN, paramsMap, "tag");
          }
        }
    
        @OnClick(R.id.btn_login)
        public void onViewClicked() {
            //点击的动画效果
            CommonUtil.animateClickView(btnLogin, new CommonUtil.ClickAnimation() {
                @Override
                public void onClick(View v) {
                    login();
                }
            });    
        }
    
        @Override
        public void onSuccess(HttpResponse httpResponse, String tag) {
            int code = httpResponse.getStatus();
            Log.i("rcw", "httpResponse=" + httpResponse);
            Log.i("rcw", "code=" + httpResponse.getStatus());
            Log.i("rcw", "data=" + httpResponse.getData());
            if (code == 200) {
                //存储账号和密码
                userBean=new UserBean();
                userBean.setAccount(etAccount.getText().toString().trim());
                userBean.setPassword(etPassword.getContent().trim());
                userBean.setUsertype(userType);
                SharePreferencesUtil.getInstance().saveUserBean(userBean);  
                //处理返回的data数据  
                String datas = new Gson().toJson(httpResponse.getData());
                LoginBean loginBean = new Gson().fromJson(datas, LoginBean.class);
                SharePreferencesUtil.getInstance().saveLoginBean(loginBean);
                Log.i("rcw", "getDeptName=" + loginBean.getDeptName());
                startActivity(new Intent(this, MainActivity.class));
                finish();
                UIUtil.toast("登录成功");
            } else if (code == 402) {
                exitToLogin(this);
            } else {
                UIUtil.toast(httpResponse.getMessage());
        }    
    
     }
    

    总结:MVP模式使得View与Model间不能直接交互,通过中间纽带Presenter实现间接联系,降低了View与Model间的耦合。MVP模式虽好,但如果项目页面相对简单,可以直接使用MVC模式实现。

    如有任何问题,欢迎评论及留言,不胜感激,谢谢!!!

    相关文章

      网友评论

          本文标题:Android开发之MVP模式

          本文链接:https://www.haomeiwen.com/subject/twdasftx.html