Android MVP框架简单实现

作者: 24K男 | 来源:发表于2017-12-11 15:05 被阅读353次

    Android MVP设计架构简单实现,其实就是为了以后编写代码的时候能偷懒。

    1. 什么是MVP

    MVP是相对MVC而言的。

    MVP代表Model,View和Presenter。

    • View层负责处理用户事件和视图部分的展示。在Android中,它可能是Activity或者Fragment类。

    • Model层负责访问数据。数据可以是远端的Server API,本地数据库或者SharedPreference等。

    • Presenter层是连接(或适配)View和Model的桥梁。

    MVC与MVP的区别

    MVC:

    1. Activity不仅要显示UI,还担任了一部分Controller的职责。
    2. 请求的业务代码往往被丢到了Activity里面,布局文件只能提供默认的UI设置,所以开发中视图层的变化也被丢到了Activity里面。
    3. Activity本身承担着控制层的责任。所以Activity就成了MVC的集合,代码严重耦合,维护的成本也越来越高。
    4. Model&View&Controller之间是可以相互作用的,造成严重的代码耦合。

    MVP:

    1. MVP与MVC最大的不同,其实是Activity职责的变化,由原来的C(控制层)变成了V(视图层),不再管控制层的问题,只管如何去显示。

    2. 控制层的角色就由我们的新人Presenter来担当,这种架构就解决了Activity过度耦合控制层和视图层的问题。

    2. MVP实践

    2.1 定义契约接口

    IContract主要是为了管理View和Model接口,这在你需要编写多个View和Model时非常有用。

    我们可以根据需要定义多个契约类,扩展IBaseView和IBaseModel接口以满足实际需求。

    /**
     * DESC:契约类,用于管理view和model。
     * 实现的view和model需要继承实现其中的接口
     * <p>
     * Created by ZhangShuai on 2017/12/11.
     */
    public interface IContract {
    
        interface IBaseView {
            void showLoading();
    
            void hideLoading();
            //.....定义其它一些共用的接口
    
        }
    
        interface IBaseModel {
            //.....定义一些共用的接口
        }
    
    }
    
    

    2.2 定义BasePresenter

    IBasePresenter

    BasePresenter在设计时考虑了RxJava。

    为了防止出现内存泄露,考虑了注销信息接口。

    /**
     * DESC:基础presenter接口
     * <p>
     * Created by ZhangShuai on 2017/12/11.
     */
    public interface IBasePresenter {
    
        //Activity关闭把view对象置为空
        void detach();
    
        //将网络请求的每一个disposable添加进入CompositeDisposable,再退出时候一并注销
        void addDisposable(Disposable subscription);
    
        //注销所有请求
        void unDisposable();
    }
    

    BasePresenter

    
    /**
     * DESC: 主要是用于添加、删除view,防止内存泄露。
     * Created by ZhangShuai on 2017/12/11.
     */
    public class BasePresenter<V extends IContract.IBaseView, M extends IContract.IBaseModel> implements IBasePresenter {
    
        CompositeDisposable mSubscriptions;
    
        protected V mView;
    
        protected M mModel;
    
        public BasePresenter(V view) {
            mView = view;
        }
    
        protected void attach(M model) {
            this.mModel = model;
        }
    
        @Override
        public void detach() {
            if (this.mView != null) {
                mView = null;
            }
            unDisposable();
        }
    
        @Override
        public void addDisposable(Disposable subscription) {
            mSubscriptions.add(subscription);
        }
    
        @Override
        public void unDisposable() {
            if (mSubscriptions.isDisposed() == false) {
                mSubscriptions.dispose();
            }
        }
    }
    

    2.3 定义BaseActivity

    /**
     * DESC: MVP BaseActivity
     * <p>
     * Created by ZhangShuai on 2017/12/11.
     */
    public abstract class BaseActivity<P extends BasePresenter>
            extends AppCompatActivity implements IContract.IBaseView {
    
        protected P mPresenter;
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            mPresenter = initPresenter();
        }
    
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            if (mPresenter != null) {
                mPresenter.detach();
                mPresenter = null;
            }
        }
    
        // 构造实际所需的prensenter
        public abstract P initPresenter();
    
    
    }
    
    

    3. 实战

    我们以一个登录页面作为实战的例子。

    3.1 定义契约类ILoginContract

    /**
     * DESC:LoginContract
     * <p>
     * Created by ZhangShuai on 2017/12/11.
     */
    
    public class ILoginContract {
    
        interface ILoginView extends IContract.IBaseView {
            // 显示信息
            void showMsg(String msg);
        }
    
        interface ILoiginModel extends IContract.IBaseModel {
            // 登录接口
            Flowable<UserInfo> login(String name, String pwd);
    
            void saveUserInfo(UserInfo info);
        }
    
    }
    
    

    ILoginContract使得我们设计的接口一目了然。

    3.2 定义Model类

    class LoginModel implements ILoginContract.ILoiginModel {
    
        private static String BASE_URL = "xxxxx";
    
        // 结合Retrofit和RxJava完成登录
        @Override
        public Flowable<UserInfo> login(String name, String pwd) {
            Retrofit retrofit = new Retrofit.Builder().baseUrl(BASE_URL).
                    addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                    .build();
    
            MyService api = retrofit.create(MyService.class);
    
            return api.login(name, pwd);
        }
    
        @Override
        public void saveUserInfo(UserInfo info) {
            // 保存用户信息
        }
    }
    
    

    3.3 定义Presenter

    class LoginPresenter extends
            BasePresenter<ILoginContract.ILoginView, ILoginContract.ILoiginModel> {
    
    
        public LoginPresenter(ILoginContract.ILoginView view) {
            super(view);
            LoginModel model = new LoginModel();
            attach(model);
        }
    
    
        public void login(String name, String pwd) {
            mView.showLoading();
    
            mModel.login(name, pwd)
                    .subscribeOn(Schedulers.newThread())
                    .observeOn(AndroidSchedulers.mainThread())
                    .doOnNext(new Consumer<UserInfo>() {
                        @Override
                        public void accept(UserInfo userInfo) throws Exception {
                            mModel.saveUserInfo(userInfo);
                        }
                    })
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Subscriber<UserInfo>() {
                        @Override
                        public void onSubscribe(Subscription s) {
    
                        }
    
                        @Override
                        public void onNext(UserInfo userInfo) {
                            mView.showMsg("Login Successful.");
                        }
    
                        @Override
                        public void onError(Throwable t) {
                            mView.showMsg("Login fail.");
                            mView.hideLoading();
                        }
    
                        @Override
                        public void onComplete() {
                            mView.hideLoading();
                        }
                    });
        }
    
    
    }
    
    

    3.4 定义View

    其实就是Activity

    
    public class DemoActivity extends BaseActivity<LoginPresenter> implements ILoginContract.ILoginView {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_demo);
        }
    
        @Override
        protected void onResume() {
            super.onResume();
            mPresenter.login("213", "456");
        }
    
        @Override
        public LoginPresenter initPresenter() {
            return new LoginPresenter(DemoActivity.this);
    
        }
    
        @Override
        public void showMsg(String msg) {
            Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
    
        }
    
        @Override
        public void showLoading() {
            //显示进度框
        }
    
        @Override
        public void hideLoading() {
            //隐藏进度框
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
        }
    }
    
    
    

    4. 总结

    在简单的设计中,MVP的代码看起来有些复杂和冗余,但是随着APP的功能不断丰富,MVP将是你的不二选择。

    MVP的结构实现起来相对简单,且大家在生活中经常用到,相信通过本文章,你能更加的深入了解MVP的大致结构和框架,并在实际开发中应用起来。

    相关文章

      网友评论

        本文标题:Android MVP框架简单实现

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