为什么要抽取?
- 每一个页面都用到同样的内容,每次都写同样的代码,浪费;
- 规定代码的编写规范;
- 多人开发维护变得简单。
抽取那些内容
设计模式
具体抽取
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() {
}
}
public class BaseModel {
}
public interface BaseView {
}
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;
}
}
public interface BaseCallBack<T, M> {
void onSuccess(T t);
void onFail(M m);
}
MVP抽取案例使用(登录)
public class LoginModel extends BaseModel {
public void login(String name, String password, BaseCallBack<String, String> callBack) {
if (true) {
callBack.onSuccess("登录成功");
} else {
callBack.onFail("登录失败");
}
}
}
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);
}
}
}
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的页面)
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() {}
}
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抽取
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();
}
}
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();
public abstract class BaseModel {
//用于统一切断观察者与被观察者关系
CompositeDisposable compositeDisposable = new CompositeDisposable();
//切断,P层调用
public void destroy() {
compositeDisposable.clear();
}
}
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;
}
}
}
/**
* 页面关闭时
* 切断连接
* 内存回收
*/
@Override
protected void onDestroy() {
super.onDestroy();
if (presenter != null) {
presenter.destroy();
}
}
网友评论