Mvp抽取

作者: 小慧sir | 来源:发表于2019-08-02 20:46 被阅读0次

为什么要抽取?

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

抽取那些内容

通用的操作

设计模式

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

具体抽取

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抽取

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

  • Mvp抽取

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

  • MVP抽取

    描述: 当我们的逻辑功能越来越多,每个功能点都要写一套MVP,是一件很繁琐的事情。因此我们要对MVP的进行封装和抽...

  • MVP抽取

    为什么要抽取? 每一个页面都用到同样的内容,每次都写同样的代码,浪费; 规定代码的编写规范; 多人开发维护变得简单...

  • MVP抽取

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

  • MVP 终极抽取(下)

    流程图: 通过MVP终极抽取(上)让我们可以知道Model 的抽取。那么开始view ,presenter 的抽取...

  • 自制MVP基类框架依赖库和工具类(自用)

    抽取 除了mvp层的抽取,还有对Activity、Adapter、Fragment的抽取 工具类 验证码工具类:C...

  • MVP抽取.md

    让子类的工作模式都按父类的执行 一个抽象类公开定义了执行它的方法的方式 网络抽取 HttpManager RxUt...

  • Mvp_抽取

    1.BaseActivity层 2.BaseCallBack层(与BaseView层相同) 3.Baseview层...

  • MVP终极抽取(上)

    流程图: 首先创建model 层 并且对他的请求参数,网络请求,数据参数,进行封装,这样可以减小相似代码。更简洁。...

网友评论

    本文标题:Mvp抽取

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