在使用rxjava+retrofit处理网络请求的时候,一般会采用对观察者进行封装,实现代码复用和拓展
public class FObserver<T> implements Observer<T> {
private Disposable mDisposable;
private ResultCallback mCallback;
public FObserver(ResultCallback callback) {
this.mCallback = callback;
}
@Override
public void onSubscribe(Disposable d) {
this.mDisposable = d;
}
@Override
public void onNext(T t) {
try {
doOnNext(t);
} catch (Exception e) {
// FLog.e(e);
onError(e);
}
disposeObserver();
}
public void doOnNext(T t) throws Exception {
if (mCallback != null) {
mCallback.onResult(t);
}
}
@Override
public void onError(Throwable e) {
// FLog.d("onError + " + e);
FResult result = new FResult(FError.GENERAL_ERROR);
result.setExceptionClassName(e.getClass().getSimpleName());
if (e instanceof HttpException) {
result = parseHttpException((HttpException) e);
} else if (e instanceof NetworkErrorException
|| e instanceof SocketTimeoutException
|| e instanceof ConnectException
|| e instanceof SocketException
|| e instanceof UnknownHostException
|| e instanceof NoRouteToHostException
|| e instanceof TimeoutException) {
result.setErrorCode(FError.NETWORK_ERROR.getValue());
}else if(e instanceof JsonSyntaxException){
result.setErrorCode(FError.JSON_PARSER_ERROR.getValue());
}
try {
onError(result);
} catch (Throwable throwable) {
FLog.e(throwable);
} finally {
disposeObserver();
}
}
private FResult parseHttpException(HttpException httpException) {
FResult result = new FResult(FError.HTTP_ERROR);
try {
result.setHttpCode(httpException.code());
result.setExceptionClassName(httpException.getClass().getSimpleName());
String errorBodyStr = httpException.response().errorBody().string();
JsonObject errorBody = new Gson().fromJson(errorBodyStr, JsonObject.class);
result.setTimestamp(getJsonValue(errorBody, "timestamp"));
result.setStatus(getJsonValue(errorBody, "status"));
result.setMessage(getJsonValue(errorBody, "error"));
result.setException(getJsonValue(errorBody, "exception"));
result.setException(getJsonValue(errorBody, "message"));
result.setPath(getJsonValue(errorBody, "path"));
} catch (IOException | JsonIOException e) {
FLog.e(e);
}
return result;
}
public static String getJsonValue(JsonObject object, String elementName) {
if (object == null || TextUtils.isEmpty(elementName)) {
return "";
}
if (!object.has(elementName)) {
return "";
}
if (object.get(elementName).isJsonNull()) {
return "";
}
return object.get(elementName).getAsString();
}
public void onError(FResult result) {
if (mCallback != null) {
mCallback.onError(result);
}
}
@Override
public void onComplete() {
disposeObserver();
}
private void disposeObserver() {
try {
if (mDisposable != null) {
mDisposable.dispose();
}
} catch (Exception ex) {
FLog.e("disposeObserver", ex);
}
}
}
public interface ResultCallback<T> {
void onError(FResult result);
void onResult(T result);
}
public class FResult {
private int errorCode;
private String exceptionClassName;
//only HttpException
private int httpCode;
//FErrorDTO content
private String timestamp;
private String status;
private String error;
private String exception;
private String message;
private String path;
public FResult(FError ferror) {
this.errorCode = ferror.getValue();
this.message = ferror.name();
}
public FResult(int errorCode, String message) {
this.errorCode = errorCode;
this.message = message;
}
public FResult(int errorCode, String message, String path, String status, String timestamp) {
this.errorCode = errorCode;
this.message = message;
this.path = path;
this.status = status;
this.timestamp = timestamp;
}
public void setErrorCode(int errorCode) {
this.errorCode = errorCode;
}
public void setExceptionClassName(String exceptionClassName) {
this.exceptionClassName = exceptionClassName;
}
public void setHttpCode(int httpCode) {
this.httpCode = httpCode;
}
public void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}
public void setStatus(String status) {
this.status = status;
}
public void setError(String error) {
this.error = error;
}
public void setException(String exception) {
this.exception = exception;
}
public void setMessage(String message) {
this.message = message;
}
public void setPath(String path) {
this.path = path;
}
private String geTime(String timestamp) {
if (timestamp == null) {
return "";
}
try {
Date date = new Date(Long.decode(timestamp));
return date.toLocaleString();
} catch (Exception e) {
FLog.e(e);
}
return "";
}
public int getErrorCode() {
return errorCode;
}
public String getExceptionClassName() {
return exceptionClassName;
}
public int getHttpCode() {
return httpCode;
}
public String getTimestamp() {
return timestamp;
}
public String getStatus() {
return status;
}
public String getError() {
return error;
}
public String getException() {
return exception;
}
public String getMessage() {
return message;
}
public String getPath() {
return path;
}
@Override
public String toString() {
return "FResult{" +
"errorCode=" + errorCode +
", exceptionClassName='" + exceptionClassName + '\'' +
", httpCode=" + httpCode +
", timestamp='" + timestamp + '\'' +
", status='" + status + '\'' +
", error='" + error + '\'' +
", exception='" + exception + '\'' +
", message='" + message + '\'' +
", path='" + path + '\'' +
'}';
}
}
应用
api.getRadioListFree(putBaseMap(request.toMap())).subscribe(
new FObserver<RadioListFreeRes>(callback));
//api
@GET(Constants.BASE_PATH + Constants.SERVICE_getLyric)
Observable<RadioListFreeRes> getRadioListFree(@QueryMap Map<String, String> map);
关于disposable
rxjava虽然好用,但是总所周知,容易遭层内存泄漏。也就说在订阅了事件后没有及时取阅,导致在activity或者fragment销毁后仍然占用着内存,无法释放。而disposable便是这个订阅事件,可以用来取消订阅
在oError和onComplete后调用disposable.dispose();
参考链接:https://www.cnblogs.com/zhujiabin/p/9294263.html