前置知识
MVP:MVP架构模式详解 - 简书 (jianshu.com)
Retrofit:Retrofit使用详解-注解介绍
RxJava:Carson带你学Android:这是一篇清晰易懂的Rxjava入门教程 - 简书 (jianshu.com)
ViewBinding:kotlin-android-extensions插件也被废弃了?
提取Base基类
在 Base
类中,我们需要做的就是把每个 Activity
或者 Fragment
等这些组件,或者对应的 MVP
层会用到的基本操作以及联系都编写好。后续模块编写的时候直接继承这些 Base
类即可,如此可以免去过多不必要的操作,让开发人员可以把精力更多的花在有意义的地方。
BaseView
BaseView
此接口是MVP模式中,用于各模块链接的关键。我们可以在此处定义好所有 Activity 和 Fragment 可能都会使用到的加载动画的调用方法
public interface BaseView { /** * 显示加载中 */ void showLoading(); /** * 操作成功隐藏dialog和显示成功 */ void SuccessHideLoading(); /** * 操作失败隐藏dialog和显示失败 */ void FailedHideLoading(); /** * 错误 * * @param bean 错误信息 */ @SuppressWarnings("rawtypes") void onErrorCode(BaseBean bean); } 复制代码
BaseBean/BaseEvent
BaseBean
/BaseEvent
这两个的用处一个是抽象出收到的 json
报文的基本字段做 Base类,供错误处理机制来自行判断处理;而 BaseEvent
则是抽象出 EventBus
的消息事件,对每个发送的消息都赋予唯一的 eventCode
,用来做消息事件识别。
public class BaseBean<T> implements Serializable { //From 测试图片 public int code; public String msg; public String message; public T data; public BaseBean(int code, String msg) { this.code = code; this.msg = msg; } } 复制代码
public class BaseEvent<T> { private int eventCode; private T data; public BaseEvent(int eventCode, T data) { this.eventCode = eventCode; this.data = data; } public int getEventCode() { return eventCode; } public void setEventCode(int eventCode) { this.eventCode = eventCode; } public T getData() { return data; } public void setData(T data) { this.data = data; } } 复制代码
BaseException
此处自定义了一个异常的基类,供外部构建类或者是获取其中的成员变量。同时它继承自 IOException
,可以作为异常被统一处理,所以也可以用来特定的处理某种异常
public class BaseException extends IOException { private String errorMsg; private int errorCode; public String getErrorMsg() { return errorMsg; } public int getErrorCode() { return errorCode; } public BaseException(String message) { this.errorMsg = message; } public BaseException(String errorMsg, Throwable cause) { super(errorMsg, cause); this.errorMsg = errorMsg; } public BaseException(int errorCode, String message) { this.errorMsg = message; this.errorCode = errorCode; } } 复制代码
BaseObserver
该类继承自 Rxjava
的 DisposableObserver
,我们创建该类,可以预重写 onStart()
、 onNext(T o)
、 onError(Throwable e)
等方法,预处理错误流;让我们再次继承的时候,只需要简洁的重写 onSuccess()
以及 onError()
即可。这个类的封装,让我们的网络请求变得十分优雅。
public abstract class BaseObserver<T> extends DisposableObserver<T> { protected BaseView view; private boolean isShowDialog; protected BaseObserver(BaseView view) { this.view = view; } /** * 带进度条的初始化方法 * * @param view view * @param isShowDialog 是否显示进度条 */ protected BaseObserver(BaseView view, boolean isShowDialog) { this.view = view; this.isShowDialog = isShowDialog; } @Override protected void onStart() { if (view != null && isShowDialog) { view.showLoading(); } } @Override public void onNext(T o) { onSuccess(o); } @Override public void onError(Throwable e) { if (view != null && isShowDialog) { view.FailedHideLoading(); } BaseException be; if (e != null) { //自定义异常 if (e instanceof BaseException) { be = (BaseException) e; //回调到view层 处理 或者根据项目情况处理 if (view != null) { view.onErrorCode(new BaseBean<>(be.getErrorCode(), be.getErrorMsg())); } else { onError(be.getErrorMsg()); } //系统异常 } else { if (e instanceof HttpException) { //HTTP错误 be = new BaseException(MyUtil.getString(R.string.BAD_NETWORK_MSG), e); } else if (e instanceof ConnectException || e instanceof UnknownHostException) { //连接错误 be = new BaseException(MyUtil.getString(R.string.CONNECT_ERROR_MSG), e); } else if (e instanceof InterruptedIOException) { //连接超时 be = new BaseException(MyUtil.getString(R.string.CONNECT_TIMEOUT_MSG), e); } else if (e instanceof JsonParseException || e instanceof JSONException || e instanceof ParseException) { //解析错误 be = new BaseException(MyUtil.getString(R.string.PARSE_ERROR_MSG), e); } else { be = new BaseException(MyUtil.getString(R.string.OTHER_MSG), e); } } } else { be = new BaseException(MyUtil.getString(R.string.OTHER_MSG)); } onError(be.getErrorMsg()); } @Override public void onComplete() { if (view != null && isShowDialog) { view.SuccessHideLoading(); } } public abstract void onSuccess(T o); public abstract void onError(String msg); } 复制代码
BasePresenter
由于我们的 Presenter
层主要作用是连接 View
层和 Model
层,对他们解耦。而当我们的 Model
层的数据处理比较少的时候,例如只有网络请求这种情况,我们就可以直接调用 addDisposable
方法发起请求,而 BaseObserver
也就是被封装好的 Model
层。这种做法是符合 迪米特原则
的方法。
public class BasePresenter<V extends BaseView> { private CompositeDisposable compositeDisposable; public V baseView; /** * 这个后面可以直接用 Example:apiServer.login(username, password); */ protected API.SZApi apiServer = RetrofitService.getInstance().getApiService(); public BasePresenter(V baseView) { this.baseView = baseView; } /** * 解除绑定 */ public void detachView() { baseView = null; removeDisposable(); } /** * 返回 view */ public V getBaseView() { return baseView; } @SuppressWarnings("all") public void addDisposable(Observable<?> observable, BaseObserver observer) { if (compositeDisposable == null) { compositeDisposable = new CompositeDisposable(); } compositeDisposable .add(observable.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribeWith(observer)); } private void removeDisposable() { if (compositeDisposable != null) { compositeDisposable.dispose(); } } } 复制代码