//ApiService.java
public interface ApiService {
@POST("app/api")
Observable<Response2> request2(@Body Request2 request);
/**
* Create a new ApiService
*/
class Factory {
private Factory() { }
public static ApiService createService( ) {
OkHttpClient.Builder builder = new OkHttpClient().newBuilder();
builder.readTimeout(10, TimeUnit.SECONDS);
builder.connectTimeout(9, TimeUnit.SECONDS);
if (BuildConfig.DEBUG) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
builder.addInterceptor(interceptor);
}
builder.addInterceptor(new HeaderInterceptor());
OkHttpClient client = builder.build();
Retrofit retrofit =
new Retrofit.Builder().baseUrl(ApiService.ENDPOINT)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
return retrofit.create(ApiService.class);
}
}
}
使用起来如下
ApiService mApiService = ApiService.Factory.createService();
mApiService.request1(request)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(Response1 response) {
int code = response.getCode();
switch (code) {
case 1: //do something
break;
case -101://do something
break;
case -102: //do something
break;
default:
break;
}
}
});
最终目标封装成如下
@POST("order/getAllOrders")
Observable<HttpResult<List<Order>>> postOrderList(@Body OrderRequest request);
ServiceFactory.orderApi()
.postOrderListState(mRequest)
.compose(new DefaultTransformer>())
.subscribe(new CommonSubscriber>(mContext) {
@Override
public void onNext(List data) {
}
@Override
protected void onError(ApiException ex) {
super.onError(ex);
ToastUtil.showShort(mContext, ex.message);
}
});
提取ApiService的Api类的创建
上面的Factory一起创建一个ServiceFactory
//https 支持
HttpsUtils.SSLParams sslParams = HttpsUtils.getSslSocketFactory(null, null, null);
sClient = new OkHttpClient().newBuilder()
.sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager)
//设置链接时间
.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
.writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
.readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
//设置拦截器
.addInterceptor(new HeaderInterceptor())
.addInterceptor(new TokenInterceptor())
.addNetworkInterceptor(new HttpLoggingInterceptor().setLevel(BuildConfig.DEBUG ? HttpLoggingInterceptor.Level.BODY : HttpLoggingInterceptor.Level.NONE))
.retryOnConnectionFailure(true)
//断网重连
.build();
OkHttpUtils.initClient(sClient);
sRetrefit = new Retrofit.Builder()
.client(sClient)
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(MyApplication.getmGson()))
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
DefaultTransformer封装
首先得了解操作符compose()和flatMap()有啥区别呢。他们都是发射出Observable,是不是就是说他们都可以复用一系列操作符呢?
compose() 是针对 Observable 自身进行变换。
compose()是唯一一个能从流中获取原生Observable
的方法,因此,影响整个流的操作符(像subscribeOn()和observeOn())需要使用compose(),相对的,如果你在flatMap()中使用subscribeOn()/observeOn(),它只影响你创建的flatMap()中的Observable,而不是整个流。
当你创建一个Observable流并且内联了一堆操作符以后,compose()会立即执行,flatMap()则是在onNext()被调用以后才会执行,换句话说,flatMap()转换的是每个项目,而compose()转换的是整个流。
flatMap()一定是低效率的,因为他每次调用onNext()之后都需要创建一个新的Observable,compose()是操作在整个流上的。
这里没有出错就转成HttpResult出错了就抛出异常
// 通过对返回码进行业务判断决定是返回错误还是正常取数据
if (httpResult.getCode() != ErrorType.SUCCESS) {
throw new ServerException(httpResult.getMessage(), httpResult.getCode());
}
return httpResult.getData();
.onErrorResumeNext(new Func1>() {
@Override
public Observable extends T> call(Throwable throwable) {
//ExceptionEngine为处理异常的驱动器
return Observable.error(ExceptionEngine.handleException(throwable));
}
});
抛出异常以后再走.onErrorResumeNext 方法
public class ServerException extends RuntimeException {
// 异常处理,为速度,不必要设置getter和setter
public int code;
public String message;
public ServerException(String message, int code) {
super(message);
this.code = code;
this.message = message;
}
}
public class ExceptionEngine {
//对应HTTP的状态码
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 ApiException handleException(Throwable e) {
ApiException ex;
if (e instanceof HttpException) { //HTTP错误
HttpException httpException = (HttpException) e;
ex = new ApiException(e, ErrorType.HTTP_ERROR);
switch (httpException.code()) {
case UNAUTHORIZED:
ex.message = "当前请求需要用户验证";
break;
case FORBIDDEN:
ex.message = "服务器已经理解请求,但是拒绝执行它";
break;
case NOT_FOUND:
ex.message = "服务器异常,请稍后再试";
break;
case REQUEST_TIMEOUT:
ex.message = "请求超时";
break;
case GATEWAY_TIMEOUT:
ex.message = "作为网关或者代理工作的服务器尝试执行请求时,未能及时从上游服务器(URI标识出的服务器,例如HTTP、FTP、LDAP)或者辅助服务器(例如DNS)收到响应";
break;
case INTERNAL_SERVER_ERROR:
ex.message = "服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理";
break;
case BAD_GATEWAY:
ex.message = "作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应";
break;
case SERVICE_UNAVAILABLE:
ex.message = "由于临时的服务器维护或者过载,服务器当前无法处理请求";
break;
default:
ex.message = "网络错误"; //其它均视为网络错误
break;
}
return ex;
} else if (e instanceof ServerException) { //服务器返回的错误
ServerException resultException = (ServerException) e;
ex = new ApiException(resultException, resultException.code);
ex.message = resultException.message;
return ex;
} else if (e instanceof JsonSyntaxException) {
// ex = new ApiException(e, ErrorType.TOKEN_INVALID);
// ex.message = "Token失效"; //均视为解析错误
ex = new ApiException(e, ErrorType.PARSE_ERROR);
ex.message = "返回数据错误"; //均视为解析错误
return ex;
} else if (e instanceof JsonParseException
|| e instanceof JSONException
|| e instanceof ParseException) {
ex = new ApiException(e, ErrorType.PARSE_ERROR);
ex.message = "解析错误"; //均视为解析错误
return ex;
} else if (e instanceof ConnectException || e instanceof SocketTimeoutException || e instanceof ConnectTimeoutException) {
ex = new ApiException(e, ErrorType.NETWORD_ERROR);
ex.message = "连接失败"; //均视为网络错误
return ex;
} else {
ex = new ApiException(e, ErrorType.UNKNOWN);
ex.message = "未知错误"; //未知错误
return ex;
}
}
最后再走CommonSubscriber.error