前一阵子博客备案由于名字问题被驳回了两次也是够了,如今在公司里一直写业务代码,这让原本就不会的算法的我算法水平更加烂,最近在跟着优酷上的一个小姐姐学魔方,智商跟不太上了啊哈哈哈哈哈。OK,步入正题,名字叫Retrofit异常处理,但是内容应该主要是针对网络的统一异常处理,我以前的异常处理都是在BaseActivity或者是BaseFragment中去添加一个方法,而后在网络请求有问题时去调用这个方法,可是后来我把我用频率较多的代码(包括Base)打包发布了一个仓库AndroidQuick,这样的话个人异常处理就无法在Base层里面处理了,并且自己的处理方式就有不少不完善的地方。java
在BaseResponse中判断请求有无错误(判断与后台约定的code等),若是不正确,带着code调用NetworkError网络统一异常处理类git
接口示例github
@FormUrlEncoded
@POST(Constants.BASE_API + "sendCode")
Flowable<BaseResponse<SendCodeBean>> getMobileCode(@FieldMap Map<String, String> values);
复制代码
BaseResponse算法
public class BaseResponse<T> {
private int code;
private String msg;
private T res;
/** * 这个方法时已经成功访问后台了,code是后台约定的错误码,判断访问是否成功 * * @param context 在作异常处理的时候可能涉及到跳转Activity * @return 返回成功或失败 */
public boolean isOk(Context context) {
if (code == 200) {
return true;
} else {
NetworkError.error(context, new ServerException(code, msg));
return false;
}
}
// get/set方法...
}
复制代码
不太会写文章,我在代码里作了详细注释。服务器
代码网络
public class NetworkError {
/** * @param context 能够用于跳转Activity等操做 */
public static void error(Context context, Throwable throwable) {
RetrofitException.ResponeThrowable responeThrowable = RetrofitException.retrofitException(throwable);
// 此处能够经过判断错误代码来实现根据不一样的错误代码作出相应的反应
switch (responeThrowable.code) {
case RetrofitException.ERROR.UNKNOWN:
case RetrofitException.ERROR.PARSE_ERROR:
case RetrofitException.ERROR.NETWORD_ERROR:
case RetrofitException.ERROR.HTTP_ERROR:
case RetrofitException.ERROR.SSL_ERROR:
Toast.makeText(context, responeThrowable.message, Toast.LENGTH_SHORT).show();
break;
case -1:
// 跳转到登录页面
context.startActivity(new Intent(context, LoginActivity.class));
// 结束除LoginActivity以外的全部Activity
AppManager.finishAllActivity(LoginActivity.class);
break;
default:
Toast.makeText(context, responeThrowable.message, Toast.LENGTH_SHORT).show();
break;
}
}
}
复制代码
public class ServerException extends RuntimeException {
public int code;
public ServerException(int code, String message) {
super(message);
this.code = code;
}
}
复制代码
这个类主要是经过instanceof操做符来判断异常的类型ui
代码this
public class RetrofitException {
private static final int UNAUTHORIZED = 401;
private static final int FORBIDDEN = 403;
private static final int NOT_FOUND = 404;
private static final int REQUEST_TIMEOUT = 408;
private static final int INTERNAL_SERVER_ERROR = 500;
private static final int BAD_GATEWAY = 502;
private static final int SERVICE_UNAVAILABLE = 503;
private static final int GATEWAY_TIMEOUT = 504;
public static ResponeThrowable retrofitException(Throwable e) {
ResponeThrowable ex;
if (e instanceof HttpException) {
HttpException httpException = (HttpException) e;
ex = new ResponeThrowable(e, ERROR.HTTP_ERROR);
switch (httpException.code()) {
case UNAUTHORIZED:
case FORBIDDEN:
case NOT_FOUND:
case REQUEST_TIMEOUT:
case GATEWAY_TIMEOUT:
case INTERNAL_SERVER_ERROR:
case BAD_GATEWAY:
case SERVICE_UNAVAILABLE:
default:
ex.message = "网络错误";
break;
}
return ex;
} else if (e instanceof ServerException) {
// 服务器下发的错误
ServerException resultException = (ServerException) e;
ex = new ResponeThrowable(resultException, resultException.code);
ex.message = resultException.getMessage();
return ex;
} else if (e instanceof JsonParseException
|| e instanceof JSONException
|| e instanceof ParseException) {
ex = new ResponeThrowable(e, ERROR.PARSE_ERROR);
ex.message = "解析错误";
return ex;
} else if (e instanceof ConnectException
|| e instanceof SocketTimeoutException
|| e instanceof UnknownHostException) {
ex = new ResponeThrowable(e, ERROR.NETWORD_ERROR);
ex.message = "链接失败";
return ex;
} else if (e instanceof SSLHandshakeException) {
ex = new ResponeThrowable(e, ERROR.SSL_ERROR);
ex.message = "证书验证失败";
return ex;
} else {
ex = new ResponeThrowable(e, ERROR.UNKNOWN);
ex.message = "未知错误";
return ex;
}
}
/** * 约定异常 */
class ERROR {
/** * 未知错误 */
public static final int UNKNOWN = 1000;
/** * 解析错误 */
public static final int PARSE_ERROR = 1001;
/** * 网络错误 */
public static final int NETWORD_ERROR = 1002;
/** * 协议出错 */
public static final int HTTP_ERROR = 1003;
/** * 证书出错 */
public static final int SSL_ERROR = 1005;
}
public static class ResponeThrowable extends Exception {
public int code;
public String message;
public ResponeThrowable(Throwable throwable, int code) {
super(throwable);
this.code = code;
}
}
}
复制代码
Map<String, String> map = new LinkedHashMap<>();
map.put("id", mId);
map.put("uid", SPUtils.getInstance().getString("uid"));
RetrofitClient
// 单例调用
.getInstance()
// 获取请求接口
.gService
// 调用接口方法
.getMobileCode(map)
// 经过compose切换线程
.compose(RxUtil.rxSchedulerHelper())
// 订阅
.subscribe(response -> {
if (response.isOk(mContext)) {
// 所有正确
} else {
// 服务器下发的错误(BaseResponse的isOk()会调用异常处理方法)
}
}, throwable -> {
LogUtils.e(throwable);
// Retrofit异常
NetworkError.error(context, throwable);
});
复制代码
https://github.com/sdwfqin/AndroidQuickspa
欢迎提供您宝贵的意见与建议,E-mail:zhangqin@sdwfqin.com线程