MVP

Mvp抽取

2019-08-02  本文已影响0人  小慧sir

为什么要抽取?

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

抽取那些内容

通用的操作

设计模式

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

具体抽取

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();
        }
    }
上一篇下一篇

猜你喜欢

热点阅读