Retrofit2+OkHttp3+RxJava2

来源:互联网 发布:泉州java培训机构 编辑:程序博客网 时间:2024/05/22 03:08

一:介绍

  • OkHttp是一个处理网络请求的开源框架。
  • Retrofit是一个基于OkHttp的可以用于Android和java的网络库。
  • RxJava是一个基于事件订阅的异步执行的一个类库。

二:简单实例,无任何封装

public class RetrofitExample {    //对应服务器的API接口    private interface IStores {        @GET("api/tms/tmsUser/updateToke")        Call<JsonObject> updateToke1(@Query("toke") String toke);        @FormUrlEncoded        @POST("api/tms/tmsUser/updateToke")        Observable<JsonObject> updateToke2(@Field("toke") String toke);    }    //Retrofit自带的Call回调    public static void updateToke1() {        new Retrofit.Builder()                .baseUrl("http://www.test.mulacar.cn:8080/")                .addConverterFactory(GsonConverterFactory.create())                .client(new OkHttpClient())                .build()                .create(IStores.class)                .updateToke1("123456")                .enqueue(new Callback<JsonObject>() {                    @Override                    public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {                        JsonObject jsonObject = response.body();                        Log.e("onResponse", jsonObject.toString());                    }                    @Override                    public void onFailure(Call<JsonObject> call, Throwable t) {                        t.printStackTrace();                    }                });    }    //Retrofit与RxJava配合使用    public static void updateToke2() {        new Retrofit.Builder()                .baseUrl("http://www.test.mulacar.cn:8080/")                .addConverterFactory(GsonConverterFactory.create())                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())                .build()                .create(IStores.class)                .updateToke2("123456")                .subscribeOn(Schedulers.newThread())                .observeOn(AndroidSchedulers.mainThread())                .subscribe(new Observer<JsonObject>() {                    @Override                    public void onSubscribe(Disposable d) {                    }                    @Override                    public void onNext(JsonObject value) {                        Log.e("onResponse", value.toString());                    }                    @Override                    public void onError(Throwable e) {                        e.printStackTrace();                    }                    @Override                    public void onComplete() {                    }                });    }}

思考???

  1. API接口中的各项注解的功能,与HTTP协议的联系?
  2. 如何构建Retrofit对象,他有哪些功能?
  3. 如何构建retrofit需要的OkHttp对象,哪些业务可以利用OkHttp来完成?
  4. retrofit如何与RxJava关联起来,哪些业务可以利用RxJava来完成?

三:Retrofit注解

  1. 请求方法注解

    1. GET注解

      • 表示发送一个GET请求。
        @GET("api/tms/tmsUser/updateToke")Observable<JsonObject> updateToke();
    2. POST注解

      • 表示发送一个POST请求。
        @POST("api/tms/tmsUser/updateToke")Observable<JsonObject> updateToke();
    3. HEAD注解

      • 表示发送一个HEAD请求。
        @HEAD("api/tms/tmsUser/updateToke")Observable<JsonObject> updateToke1();
    4. DELETE注解

      • 表示发送一个DELETE请求。
        @DELETE("api/tms/tmsUser/updateToke")Observable<JsonObject> updateToke();
    5. PUT注解

      • 表示发送一个PUT请求。
        @PUT("api/tms/tmsUser/updateToke")Observable<JsonObject> updateToke();
    6. OPTIONS注解

      • 表示发送一个OPTIONS请求。
        @OPTIONS("api/tms/tmsUser/updateToke")Observable<JsonObject> updateToke();
    7. PATCH注解

      • 表示发送一个PATCH请求。
        @PATCH("api/tms/tmsUser/updateToke")Observable<JsonObject> updateToke();
    8. HTTP注解

      • 表示发送一个自定义的HTTP请求。
        @HTTP(method = "DELETE", path = "api/tms/tmsUser/updateToke", hasBody = false)Observable<JsonObject> updateToke();
  2. 请求参数注解

    1. Query注解

      • 用于给请求添加参数,参数以键值对拼接在路径后面。
        @GET("api/tms/tmsUser/updateToke")Observable<JsonObject> updateToke(     @Query("toke") String toke);
    2. QueryMap注解

      • 用于给请求添加参数集合,参数以键值对拼接在路径后面。
        @GET("api/tms/tmsUser/updateToke")Observable<JsonObject> updateToke(     @QueryMap Map<String, Object> params);
    3. QueryName注解(新增)

      • 用于给请求添加参数,参数只有值,拼接在路径后面。
        @GET("api/tms/tmsUser/updateToke")Observable<JsonObject> updateToke(     @QueryName String toke);
    4. Field注解

      • 用于给请求添加参数,参数以键值对放在body中。
        @FormUrlEncoded@POST("api/tms/tmsUser/updateToke")Observable<JsonObject> updateToke(     @Field("toke") String toke);
    5. FieldMap注解

      • 用于给请求添加参数集合,参数以键值对放在body中。
        @FormUrlEncoded@POST("api/tms/tmsUser/updateToke")Observable<JsonObject> updateToke(     @FieldMap Map<String, Object> params);
    6. Part注解

      • 用于给请求添加参数,参数以表单形式放在body中。
        @Multipart@POST("api/tms/tmsUser/upaVatar")Observable<ApiResult<Driver>> uploadAvatar(      @Part("type") int type);
    7. PartMap注解

      • 用于给请求添加参数集合,参数以表单形式放在body中。
        @Multipart@POST("api/tms/tmsUser/upaVatar")Observable<ApiResult<Driver>> uploadAvatar(      @PartMap Map<String, RequestBody> params);
    8. Path注解

      • 用于替换请求路径中的参数。
        @GET("api/tms/{what}/updateToke")Observable<JsonObject> updateToke(     @Path("what") String toke);
    9. Body注解

      • 将一个Java类的属性转换为参数,支持POST和PUT请求。
        //实体class Repo {   final String owner;   final String name;   Repo(String owner, String name) {       this.owner = owner;       this.name = name;   }}//接口@POST("api/tms/{what}/updateToke")Observable<ResponseBody> updateToke(      @Body Repo repo);
    10. Header注解

      • 添加一个请求头参数。
        @GET("api/tms/tmsUser/updateToke")Observable<JsonObject> updateToke(     @Header("aaa") String aaa,     @Query("toke") String toke);
    11. HeaderMap注解(新增)

      • 添加一个请求头参数集合。
        @GET("api/tms/tmsUser/updateToke")Observable<JsonObject> updateToke(     @Header("aaa") String aaa,     @Query Map<String, Object> params);
    12. Headers注解

      • 添加一个请求头参数集合(写死)。
        @Headers({ "Cache-Control: max-age=640000","aaa: bbb"})@GET("api/tms/tmsUser/updateToke")Observable<JsonObject> updateToke(     @Query("toke") String toke);
  3. 其他注解

    1. FormUrlEncoded注解

      • 当用了Field或FieldMap注解时,需要使用FormUrlEncoded注解。
        @FormUrlEncoded@POST("api/tms/tmsUser/updateToke")Observable<JsonObject> updateToke(     @Field("toke") String toke);
    2. Multipart注解

      • 表示以表单方式上传。
        @Multipart@POST("api/tms/tmsUser/upaVatar")Observable<ApiResult<Driver>> uploadAvatar(      @Part("type") int type);
    3. Streaming注解

      • 表示直接获取输入流,下载文件时要用到此参数,如果不加此注释,则会把整个文件写入内存,那么大文件会内存溢出。
        @Streaming@GET("api/tms/tmsUser/download")Call<ResponseBody> download(     @QueryMap Map<String, Object> params);
    4. Url注解

      • 添加请求路径,一般已经在请求方法注解中添加了请求路径,不用再使用此注解。
        @GETObservable<JsonObject> updateToke(     @Url String url);

四:构建Retrofit对象

new Retrofit.Builder()        .baseUrl("http://www.test.mulacar.cn:8080/")        .addConverterFactory(GsonConverterFactory.create())        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())        //.client(new OkHttpClient())        //.callbackExecutor(Executors.newCachedThreadPool())        //.validateEagerly(true)        //.callFactory(myFactory)        .build();
  1. baseUrl(String baseUrl)

    • 设置请求路径
    • 当baseUrl只有域名,或者域名+端口时,末尾可以加/,也可以不加/
      • ”http://www.test.mulacar.cn:8080/“或”http://www.test.mulacar.cn:8080”
    • 当baseUrl包含有除了域名的其他路径是,必须以/结尾。
      • ”http://www.test.mulacar.cn:8080/api/”
    • 当接口方法中的路径以/开头时,表示只取baseUrl得域名和端口,后面的路径忽略。
      • 例如当baseUrl为”http://www.test.mulacar.cn:8080/api/“时
      • 如果使用@GET(“/tms/tmsUser/updateToke”),那么实际的请求连接为http://www.test.mulacar.cn:8080/tms/tmsUser/updateToke
    • 当接口方法中的路径没有以/开头时,表示取全部baseUrl。
      • 例如当baseUrl为”http://www.test.mulacar.cn:8080/api/“时
      • 如果使用@GET(“tms/tmsUser/updateToke”),那么实际的请求连接为http://www.test.mulacar.cn:8080/api/tms/tmsUser/updateToke
  2. addConverterFactory(Converter.Factory factory)

    • 设置转换工厂,用来转换发送和接收的数据。
    • 官方给我们提供了一些转换器。
      • GSON: com.squareup.retrofit:converter-gson:2.0.0-beta2
      • Moshi: com.squareup.retrofit:converter-moshi:2.0.0-beta2
      • Jackson: com.squareup.retrofit:converter-jackson:2.0.0-beta2
      • SimpleXML: com.squareup.retrofit:converter-simplexml:2.0.0-beta2
      • ProtoBuf: com.squareup.retrofit:converter-protobuf:2.0.0-beta2
      • Wire: com.squareup.retrofit:converter-wire:2.0.0-beta2
    • 自定义转换器。

      • 参考类com.mula.retrofit.ConverterFactory
      /*** 转换工厂, 将http返回结果转换为ApiResult*/public final class ConverterFactory extends Converter.Factory { public static ConverterFactory create() {     return new ConverterFactory(); } private ConverterFactory() { } @Overridepublic Converter<?, RequestBody> requestBodyConverter(    Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {     return new BeanRequestBodyConverter<>(type); } @Override public Converter<ResponseBody, ?> responseBodyConverter(         Type type, Annotation[] annotations, Retrofit retrofit) {     return new BeanResponseBodyConverter<>(type); } static final class BeanRequestBodyConverter<T> implements Converter<T, RequestBody> {     private static final MediaType MEDIA_TYPE = MediaType.parse("application/json; charset=UTF-8");     private final Type type;     public BeanRequestBodyConverter(Type type) {         this.type = type;     }     @Override     public RequestBody convert(T value) throws IOException {         String str = new Gson().toJson(value, type);         return RequestBody.create(MEDIA_TYPE, str);     } } static final class BeanResponseBodyConverter<T> implements Converter<ResponseBody, ApiResult<T>> {     private final Type type;     public BeanResponseBodyConverter(Type type) {         this.type = type;     }     @Override     public ApiResult<T> convert(ResponseBody value) throws IOException {         String responseStr = value.string();         L.e("result:" + responseStr);         ApiResult<T> apiResult;         try {             JsonObject jsonObject = new JsonParser().parse(responseStr).getAsJsonObject();             String code = jsonObject.get("code").getAsString();             if ("success".equals(code)) {                 apiResult = new Gson().fromJson(responseStr, type);             } else {                 apiResult = new ApiResult<>();                 apiResult.setType(false);                 apiResult.setCode(code);                 apiResult.setMessage(jsonObject.get("message").getAsString());             }         } catch (Exception e) {             e.printStackTrace();             apiResult = new ApiResult<>();             apiResult.setStatus(ApiResult.Status.ERROR_JSON);             apiResult.setMessage("json_error");         }         apiResult.setJsonStr(responseStr);         return apiResult;     } }}
  3. addCallAdapterFactory(CallAdapter.Factory factory)

    • 设置回调适配器,默认的CallAdapter是返回一个Call对象。
    • 使用RxJava的CallAdapter

      .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
    • 使用RxJava2的CallAdapter(注意多了一个2)

      .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
  4. client(OkHttpClient client)

    • 设置自定义OkHttpClient对象。
    • 具体OkHttpClient的定义参考下面第五大条。
  5. callFactory(okhttp3.Call.Factory factory)

    • 用来处理okhttp的Request对象
  6. validateEagerly(boolean validateEagerly)

    • 调用生成的实例时,急切地验证所提供的接口中所有方法的配置,默认为false。
    • 即当Retrofit的create方法调用时,是否验立刻证接口中的所以方法的配置。
  7. callbackExecutor(Executor executor)

    • 设置从服务方法返回结果的执行线程池。
    • 但当调用了addCallAdapterFactory方法,设置了自己的回调适配器时,该方法将失效。

五:构建OkHttp对象

OkHttpClient okHttpClient = new OkHttpClient.Builder()            .retryOnConnectionFailure(true)// 连接失败重连,默认为true,可以不加            .connectTimeout(TIMEOUT, TimeUnit.SECONDS)// 链接超时            .writeTimeout(TIMEOUT, TimeUnit.SECONDS)// 写入超时            .readTimeout(TIMEOUT, TimeUnit.SECONDS)// 读取超时            .cookieJar(new CookiesManager())// 开启cookie功能,将cookie序列化到本地            //.sslSocketFactory(new SSLSocketFactory())// 可以用来支持https协议            .addInterceptor(new AppInterceptor())// 添加自定义拦截操作            .build();

六:与RxJava联合使用

1.Retrofit需要设置addCallAdapterFactory为RxJava2CallAdapterFactory.create()

.addCallAdapterFactory(RxJava2CallAdapterFactory.create())

2.接口的返回值需要定义为Observable<T>,返回的便是RxJava中的Observable

@FormUrlEncoded@POST("api/tms/tmsUser/updateToke")Observable<JsonObject> updateToke(@Field("toke") String toke);

3.完整实例

new Retrofit.Builder()        .baseUrl("http://www.test.mulacar.cn:8080/")        .addConverterFactory(GsonConverterFactory.create())        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())        .build()// 创建Retrofit        .create(IStores.class)// 创建请求接口        .updateToke2("123456")// 调用接口方法,此处返回Observable,以下代码完全为RxJava的用法        .subscribeOn(Schedulers.newThread())// 切换到子线程发起网络请求        .observeOn(AndroidSchedulers.mainThread())// 订阅的返回结果切换到主线程        .subscribe(new Observer<JsonObject>() {            @Override            public void onSubscribe(Disposable d) {                // 此处的Disposable可以用来取消返回结果的订阅            }            @Override            public void onNext(JsonObject value) {            // 此处拿到返回的结果                Log.e("onResponse", value.toString());            }            @Override            public void onError(Throwable e) {                // 此处为发生错误回调                e.printStackTrace();            }            @Override            public void onComplete() {                // 完成            }        });}