MVP抽取

作者: Anwfly | 来源:发表于2019-06-30 23:57 被阅读178次

    为什么要抽取?

    • 每一个页面都用到同样的内容,每次都写同样的代码,浪费;
    • 规定代码的编写规范;
    • 多人开发维护变得简单。

    抽取那些内容

    • 通用的操作

    设计模式

    • 模板设计模式(让子类的工作模式都按照父类的执行)

    具体抽取

    • BaseActivity抽取
    public abstract class BaseActivity<P extends BasePresenter, M extends BaseModel, V extends BaseView> extends AppCompatActivity {
    
        protected P presenter;
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(getLayoutId());
            ButterKnife.bind(this);
            presenter= initPresenter();//每个页面都需要
            if (presenter!= null) {
                presenter.setBaseModel(initMVPModel());
                presenter.setBaseView(initMVPView());
            }
            initView();//有些子类需要,有些不需要
            initData();//有些子类需要,有些不需要,仅仅用普通方法即可
            initListener();
        }
    
        protected abstract V initMVPView();
    
        protected abstract P initPresenter();
    
        protected abstract M initMVPModel();
    
        protected abstract int getLayoutId();
        
        private void initListener() {
    
        }
    
        private void initData() {
    
        }
    
        protected void initView() {
        }
    }
    
    • BaseModel抽取
    public class BaseModel {
    }
    
    • BaseView 抽取
    public interface BaseView {
    }
    
    • BasePresenter抽取
    public abstract class BasePresenter<M extends BaseModel, V extends BaseView> {
        protected M model;
        protected V view;
    
        //使用set方法赋值
        public void setBaseModel(M baseModel) {
            this.model= baseModel;
        }
    
        public void setBaseView(V baseView) {
            this.view= baseView;
        }
    }
    
    • callback抽取
    public interface BaseCallBack<T, M> {
        void onSuccess(T t);
        void onFail(M m);
    }
    

    MVP抽取案例使用(登录)

    • M层
    public class LoginModel extends BaseModel {
        public void login(String name, String password, BaseCallBack<String, String> callBack) {
            if (true) {
                callBack.onSuccess("登录成功");
            } else {
                callBack.onFail("登录失败");
            }
        }
    }
    
    • P层
    public class LoginPresenter extends BasePresenter<LoginView, LoginModel> implements BaseCallBack<String, String> {
        public void login(String name, String pwd) {
            if (model != null) {
                model .login(name, pwd, this);
            }
        }
    
        @Override
        public void onSuccess(String s) {
            if (view != null) {
                view .onSuccess(s);
            }
        }
    
        @Override
        public void onFail(String s) {
            if (view  != null) {
                view .onFail(s);
            }
        }
    }
    
    • V层
    public class MainActivity extends BaseActivity<LoginPresenter, LoginView, LoginModel> implements LoginView {
    
        @BindView(R.id.btn_login)
        Button btnLogin;
    
        @Override
        protected int getLayoutId() {
            return R.layout.activity_main;
        }
    
        @Override
        protected LoginView initMvpView() {
            return this;
        }
    
        @Override
        protected LoginModel initMvpModel() {
            return new LoginModel();
        }
    
        @Override
        protected LoginPresenter initPresnter() {
            return new LoginPresenter();
        }
    
        @Override
        public void onSuccess(String s) {
            Toast.makeText(MainActivity.this, s, Toast.LENGTH_SHORT).show();
        }
    
        @Override
        public void onFail(String s) {
            Toast.makeText(MainActivity.this, s, Toast.LENGTH_SHORT).show();
        }
    
        @OnClick({R.id.btn_login})
        public void onViewClicked(View view) {
                    baseP.login("", "");   
        }
    

    MVP与普通的分离(不需要mvp的页面)

    • 不需要MVP
    public abstract class BaseActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(getLayoutId());
            ButterKnife.bind(this);
            initMvp();
            initView();//有些子类需要,有些不需要
            initData();//有些子类需要,有些不需要,仅仅用普通方法即可
            initListener();
        }
    
       private void initMvp() {}
    
        protected abstract int getLayoutId();
        
        private void initListener() {}
    
        private void initData() {}
    
        protected void initView() {}
    }
    
    • 需要mvp
    public abstract class BaseMVPActivity<P extends BasePresenter, V extends BaseView, M extends BaseModel> extends BaseActivity {
        protected P presenter;
    
        @Override
        public void initMvp() {
            super.initMvp();
    
            presenter = initPresnter();
            if (presenter != null) {
                presenter.addView(initMvpView());
                presenter.addModel(initMvpModel());
            }
        }
    
        protected abstract V initMvpView();
    
        protected abstract M initMvpModel();
    
        protected abstract P initPresnter();
    }
    

    Fragment抽取

    • 没有MVP抽取基类
    public abstract class BaseFragment extends Fragment {
    
        private Unbinder unbinder;
    
        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            View view = inflater.inflate(getLayoutId(), container, false);
            unbinder = ButterKnife.bind(this, view);
            initMvp();
            initView();
            initData();
            initListener();
            return view;
        }
    
        protected void initMvp() {
    
        }
    
        protected void initListener() {
    
        }
    
        protected void initData() {
    
        }
    
        protected void initView() {
    
        }
    
        protected abstract int getLayoutId();
    
        @Override
        public void onDestroyView() {
            super.onDestroyView();
            unbinder.unbind();
        }
    }
    
    • 有MVP抽取
    public abstract class BaseMvpFragment<P extends BasePresenter, V extends BaseView, M extends BaseModel> extends BaseFragment {
        protected P presenter;
    
        @Override
        protected void initMvp() {
            super.initMvp();
            presenter = initPresnter();
            if (presenter != null) {
                presenter.addView(initMvpView());
                presenter.addModel(initMvpModel());
            }
        }
    
        protected abstract V initMvpView();
    
        protected abstract M initMvpModel();
    
        protected abstract P initPresnter();
    }
    

    应用崩溃问题解决

    • 背景:在发动网络请求的时候,退出当前activity
    • 冲突:此时如果回到主线程更新UI,APP会崩溃
    • 解决:当activity退出时,调用DisPosable.dispose()切断观察者和被观察者的连接,使得观察者无法收到事件&响应事件;当出现多个disposable时,采用Rxjava内置容器CompositeDisposable进行统一管理
    CompositeDisposable compositeDisposable = new CompositeDisposable();
    //添加disposable到CompositeDisposable容器
    compositeDisposable .add();
    //清空CompositeDisposable容器,在父类的baseModel中调用
    compositeDisposable .clear();
    
    • 在BaseModel中
    public abstract class BaseModel {
        
        //用于统一切断观察者与被观察者关系
        CompositeDisposable compositeDisposable = new CompositeDisposable();
    
        //切断,P层调用
        public void destroy() {
            compositeDisposable.clear();
        }
    }
    
    • 在basePresenter中
    public class BasePresenter<V extends BaseView, M extends BaseModel> {
    
        //创建一个集合,用于存放model
        protected ArrayList<BaseModel> list = new ArrayList<BaseModel>();
    
        protected V view;
        protected M model;
    
        public void addView(V v) {
            this.view = v;
        }
    
        public void addModel(M m) {
            this.model = m;
            //添加model
            list.add(m);
        }
    
        public void destroy() {
            //如果view不为空,页面关闭,强制置空,否则内存泄漏
            if (view != null) {
                view = null;
            }
    
            //如果页面关闭,切断网络请求的观察者与被观察者的关系
            if (list.size() > 0) {
                for (BaseModel baseModel : list) {
                    baseModel.destroy();
                }
            }
    
            //如果model不为空,置空
            if (model != null) {
                model = null;
            }
        }
    }
    
    • 在BaseMVPActivity中
      /**
         * 页面关闭时
         * 切断连接
         * 内存回收
         */
        @Override
        protected void onDestroy() {
            super.onDestroy();
            if (presenter != null) {
                presenter.destroy();
            }
        }
    

    相关文章

      网友评论

        本文标题:MVP抽取

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