RXjava+Retrofit封装:对观察者Observer进行封装,实现代码复用和拓展

在使用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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于Android项目中的网络请求,RxJavaRetrofit和MVP是常用的框架组合。下面是一个简单的网络框架封装示例: 首先,在项目中引入RxJavaRetrofit的依赖。 ``` implementation 'io.reactivex.rxjava2:rxjava:2.2.19' implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' implementation 'com.squareup.retrofit2:adapter-rxjava2:2.9.0' ``` 然后,创建一个Retrofit的单例类,用于进行网络请求的初始化和配置。 ```java public class RetrofitClient { private static Retrofit retrofit; private static final String BASE_URL = "https://api.example.com/"; public static Retrofit getClient() { if (retrofit == null) { retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build(); } return retrofit; } } ``` 接下来,创建一个ApiService接口,定义网络请求的方法。 ```java public interface ApiService { @GET("users") Observable<List<User>> getUsers(); } ``` 然后,创建一个DataManager类,用于管理网络请求。 ```java public class DataManager { private ApiService apiService; public DataManager() { apiService = RetrofitClient.getClient().create(ApiService.class); } public Observable<List<User>> getUsers() { return apiService.getUsers(); } } ``` 最后,在MVP的Presenter中调用DataManager类进行网络请求。 ```java public class UserPresenter { private UserView userView; private DataManager dataManager; public UserPresenter(UserView userView) { this.userView = userView; dataManager = new DataManager(); } public void getUsers() { dataManager.getUsers() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<List<User>>() { @Override public void onSubscribe(Disposable d) { // 在请求开始时的操作 } @Override public void onNext(List<User> users) { // 请求成功返回数据时的操作 userView.showUsers(users); } @Override public void onError(Throwable e) { // 请求失败时的操作 userView.showError(e.getMessage()); } @Override public void onComplete() { // 请求完成时的操作 } }); } } ``` 这样,就完成了一个简单的Android RxJava + Retrofit + MVP网络框架封装。你可以根据自己的需要,进行进一步的封装和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值