处理前
使用r2+r2组合 以下代码很常见
只有返回的数据能解析成即有格式时 会走onNext
我们往往还要进一步判断
常见的是判断成功/失败的标志字段
对于onError
我们一般都是弹出提示
如果服务端返还格式不规范也不会走onNext
异常处理我们显得很无力
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| ApiManager.getApi().XXXXXXX(ObjectHelper.toMap(quickDeliverDTO)) .compose(this.bindToLifecycle()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<ApiResult<String>>() { @Override public void onComplete() {
}
@Override public void onError(Throwable e) {
}
@Override public void onSubscribe(@NonNull Disposable d) {
}
@Override public void onNext(ApiResult<String> stringApiResult) { } });
|
我们希望可以。。。
1.自定义错误处理
2.成功/失败标志不要手动判断 成功走单独回调
3.失败时 默认方法提示错误,不用每次手写弹窗
4.没有网络连接时,不发起请求,走失败回调
5.保留原有回调 应对特殊情况
自定义Converter 捕获异常
CustomGsonResponseBodyConverter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| class CustomGsonResponseBodyConverter<T> implements Converter<ResponseBody, T> { private final Gson gson; private final TypeAdapter<T> adapter;
CustomGsonResponseBodyConverter(Gson gson, TypeAdapter<T> adapter) { this.gson = gson; this.adapter = adapter; }
@Override public T convert(ResponseBody value) throws IOException { String response = value.string(); HttpStatus httpStatus = gson.fromJson(response, HttpStatus.class); if (!httpStatus.isSuccess()) { value.close(); throw new ApiException(httpStatus.getCode(), httpStatus.getMessage()); }
MediaType contentType = value.contentType(); Charset charset = contentType != null ? contentType.charset(UTF_8) : UTF_8; InputStream inputStream = new ByteArrayInputStream(response.getBytes()); Reader reader = new InputStreamReader(inputStream, charset); JsonReader jsonReader = gson.newJsonReader(reader);
try { return adapter.read(jsonReader); } finally { value.close(); } } }
|
CustomGsonRequestBodyConverter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| final class CustomGsonRequestBodyConverter<T> implements Converter<T, RequestBody> { private static final MediaType MEDIA_TYPE = MediaType.parse("application/json; charset=UTF-8"); private static final Charset UTF_8 = Charset.forName("UTF-8");
private final Gson gson; private final TypeAdapter<T> adapter;
CustomGsonRequestBodyConverter(Gson gson, TypeAdapter<T> adapter) { this.gson = gson; this.adapter = adapter; }
@Override public RequestBody convert(T value) throws IOException { Buffer buffer = new Buffer(); Writer writer = new OutputStreamWriter(buffer.outputStream(), UTF_8); JsonWriter jsonWriter = gson.newJsonWriter(writer); adapter.write(jsonWriter, value); jsonWriter.close(); return RequestBody.create(MEDIA_TYPE, buffer.readByteString()); } }
|
CustomGsonResponseBodyConverter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| class CustomGsonResponseBodyConverter<T> implements Converter<ResponseBody, T> { private final Gson gson; private final TypeAdapter<T> adapter;
CustomGsonResponseBodyConverter(Gson gson, TypeAdapter<T> adapter) { this.gson = gson; this.adapter = adapter; }
@Override public T convert(ResponseBody value) throws IOException { String response = value.string(); HttpStatus httpStatus = gson.fromJson(response, HttpStatus.class); if (!httpStatus.isSuccess()) { value.close(); throw new ApiException(httpStatus.getCode(), httpStatus.getMessage()); }
MediaType contentType = value.contentType(); Charset charset = contentType != null ? contentType.charset(UTF_8) : UTF_8; InputStream inputStream = new ByteArrayInputStream(response.getBytes()); Reader reader = new InputStreamReader(inputStream, charset); JsonReader jsonReader = gson.newJsonReader(reader);
try { return adapter.read(jsonReader); } finally { value.close(); } } }
|
其他相关类
HttpStatus.java
对应接口异常时的返回,不关心返回数据的解析,只解析code,message
如
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class HttpStatus { @SerializedName("resultCode") private int mCode; @SerializedName("resultMsg") private String mMessage;
public int getCode() { return mCode; }
public String getMessage() { return mMessage; } }
|
ApiException.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| public class ApiException extends RuntimeException { private int mErrorCode; private String errorMessage;
public String getErrorMessage() { return errorMessage; }
public void setErrorMessage(String errorMessage) { this.errorMessage = errorMessage; }
public int getErrorCode() { return mErrorCode; }
public void setErrorCode(int errorCode) { mErrorCode = errorCode; }
public ApiException(int errorCode, String errorMessage) { super(errorMessage); this.mErrorCode = errorCode; this.errorMessage = errorMessage; }
}
|
自定义 Observer
实现常用处理 免去复写
DisposableObserver 实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
| public abstract class BaseDisposableObserver<T> extends DisposableObserver<ApiResult<T>> {
private final int RESPONSE_CODE_OK = 1; private final int RESPONSE_CODE_FAILED = 2; private Context mContext; private static Gson gson = new Gson(); private int errorCode; private String errorMsg = "未知的错误!";
public BaseDisposableObserver(Context context) { this.mContext = context; }
@Override protected void onStart() { if (!NetworkUtils.isConnected()) { errorCode = RESPONSE_CODE_FAILED; errorMsg = "没有网络,请检查网络连接"; onFailure(errorCode,errorMsg); } }
public abstract void onSuccess(T t);
@Override public void onNext(@NonNull ApiResult<T> response) { if (response.getResultCode() == RESPONSE_CODE_OK) { onSuccess(response.getObject()); } else { onFailure(response.getResultCode(), response.getResultMsg()); }
}
@Override public void onError(@NonNull Throwable t) { L.d(t.getMessage());
if (t instanceof HttpException) { HttpException httpException = (HttpException) t; errorCode = httpException.code(); errorMsg = httpException.getMessage(); getErrorMsg(httpException); } else if (t instanceof ApiException) { ApiException exception = (ApiException) t; errorCode = exception.getErrorCode(); errorMsg = exception.getErrorMessage(); } else if (t instanceof SocketTimeoutException) { errorCode = RESPONSE_CODE_FAILED; errorMsg = "服务器响应超时"; } else if (t instanceof ConnectException) { errorCode = RESPONSE_CODE_FAILED; errorMsg = "网络连接异常,请检查网络"; } else if (t instanceof RuntimeException) { errorCode = RESPONSE_CODE_FAILED; errorMsg = "运行时错误"; } else if (t instanceof UnknownHostException) { errorCode = RESPONSE_CODE_FAILED; errorMsg = "无法解析主机,请检查网络连接"; } else if (t instanceof UnknownServiceException) { errorCode = RESPONSE_CODE_FAILED; errorMsg = "未知的服务器错误"; } else if (t instanceof IOException) { errorCode = RESPONSE_CODE_FAILED; errorMsg = "没有网络,请检查网络连接"; } onFailure(errorCode, errorMsg);
}
@CallSuper public void onFailure(int code, String message) { switch (code) {
case 4: Intent intent = new Intent(); intent.setClass(mContext, LoginActivity.class); mContext.startActivity(intent); break; } Toast.makeText(mContext, message + " code=" + code, Toast.LENGTH_SHORT).show(); }
private void getErrorMsg(HttpException httpException) { }
@Override public void onComplete() {
} }
|
Observer 实现也类似
1 2 3 4
| public abstract class BaseObserver <T> implements Observer<ApiResult<T>> {
..... }
|
代码使用
1 2 3 4 5 6 7 8 9 10 11 12 13
| ApiManager.getSmartApi().login(mNameEdit.getText().toString(), mPassEdit.getText().toString()) .compose(this.bindToLifecycle()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new BaseDisposableObserver<String>(getActivity()) { @Override public void onSuccess(String s) { startActivity(new Intent(getActivity(),MainActivity.class)); BasePreference.getInstance().saveToken(s); }
}) ;
|
1.没网络时 不请求直接onFailure
2.数据解析成功且标志位置成功时 onSuccess
3.其他走onFailure
onFailure
默认弹出提示框提示错误代码 错误信息
token失效时返回登录页面
最重要的是默认onFailure
处理都不用另写了!
当然也可以子类实现 不用默认处理 Observer的默认回调都在