retrofit:简介

Photo by Danyu Wang on Unsplash

作为目前Android最流行的Http Client框架之一,retrofit的学习已是大势所趋。
学习于:
http://www.jianshu.com/p/308f3c54abdd
http://blog.csdn.net/sk719887916/article/details/51755427

以下代码示例是retrofit的原始形态,分为两部分:

一是定义一个接口,其中@GET("api/public")表示请求方式和请求的路径;@Query("uid") String uid表示需要传入String类型的参数,对应的参数名是"uid";泛型代表着HTTP响应体转换的类型,此时是ResponseBody

public interface ApiService {
    @GET("api/public")
    Call<ResponseBody> getData(@Query("uid") String uid);
}

二是创建retrofit实例,baseUrl表示请求的域名,同上述请求路径,参数组成完整的网址;然后创建上述接口的代理对象,调用异步方法,响应成功后走onResponse,失败走onFailure

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com/")
    .build();

apiService = retrofit.create(ApiService.class);

apiService .enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
            }
            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
            }
        });

当然实际应用中要比上述中复杂的多,本系列将基于retrofit 2依次学习:注解,Converter,CallAdapter;

添加依赖:

compile 'com.squareup.retrofit2:retrofit:2.2.0'

注解

Retrofit 共22个注解,分为三类:HTTP请求方式,标记类,参数类;

HTTP请求方式:@GET,@POST

  • 因为Retrofit 2.0使用了新的URL定义方式,BaseUrl与@POST 不是简单的组合在一起,所以BaseUrl根域名和@POST 中路径组合时应按照:BaseUrl: 以 / 结尾,@GET或者@POST: 不以 / 开头的标准,如图所示:

    否则将出现的问题,如下图所示:


标记类:@FormUrlEncoded,@Multipart,@Streaming

  • @FormUrlEncoded
    表明是一个表单格式的请求(Content-Type:application/x-www-form-urlencoded)

  • @Multipart
    表明是一个请求体支持文件上传的请求(Content-Type:multipart/form-data)

    • Content-Type只能是一种类型,不能同时使用上面两种注解。
  • @Streaming
    下载大文件需要注入,防止下载过程中写入到内存中


参数类:@Field,@FieldMap,@Query,@QueryMap,@Url,@Path,@Part,@Body

  • @Field@FieldMap

用于@post请求方式时传递简单的键值对,@Field@FieldMap传递的参数时放在请求体的。额外需要添加@FormUrlEncoded表示表单提交。

如果在@post请求中使用@Field@FieldMap时去掉@FromUrlEncoded,那么程序会抛出java.lang.IllegalArgumentException: @Field parameters can only be used with form encoding. (parameter #1)的错误异常。

如果将@FromUrlEncoded添加在@GET上面,同样的也会抛出
java.lang.IllegalArgumentException:FormUrlEncoded can only be specified on HTTP methods with request body (e.g., @POST).的错误异常。

    //一个参数
    @FormUrlEncoded
    @POST("API/public")
    Call<ResponseBody> postData(@Field("uid") String uid);

    //参数较多
    @FormUrlEncoded
    @POST("API/public")
    Call<ResponseBody> postData(@FieldMap Map<String, String> params);
  • @Query@QueryMap
    用于@get请求方式,传递简单的键值对,参数将直接拼接在url后面的
    //只有一个参数且参数key值:uid
    @GET("API/public")
    Call<ResponseBody> getData(@Query("uid") String uid);

    //参数较多
    @GET("API/public")
    Call<ResponseBody> getData(@QueryMap Map<String, String> params);
  • @Url
    使用全路径复写baseUrl,适用于非统一baseUrl的场景,意思是当@GET@POST注解的url为全路径时(如果和baseUrl不是一个路径),会直接使用@Url注解中新的路径。

  • @Path
    用于替换和动态更新,如下所示使用@Path时,id 所表示的路径中不能包含”/”,否则会将其转化为%2F。

  • @Part
    实现图片和参数上传,如果图片不确定@PartMap() Map<String, RequestBody> maps代替@Part MultipartBody.Part file

 @Multipart
 @POST("API/public")
 Call<ResponseBody> upload(@PartMap Map<String, String> params,//参数集合
                          @Part MultipartBody.Part file);//图片
// 封装 请求参数集合 map
   ...
// 封装 请求RequestBody
RequestBody requestFile =
        RequestBody.create(MediaType.parse("multipart/form-data"), file);
MultipartBody.Part body =
        MultipartBody.Part.createFormData("image", file.getName(), requestFile);
//
Call<ResponseBody> call = service.upload(maps,description,body);
    ...
  • @Body
    也可以实现多张图片和参数的上传
//上传图片
@POST("API/public/ChangeUserImg")
Call<ResponseBody> upFile(@Body RequestBody Body);
MultipartBody.Builder builder = new MultipartBody.Builder()
           .setType(MultipartBody.FORM)
           .addFormDataPart("uid", mUid)
           .addFormDataPart("pid", mPid);

for (int i = 0; i < mPathList.size(); i++) {
      File file = new File(mPathList.get(i));
      builder.addFormDataPart("file" + i, file.getName(), RequestBody.create(MediaType.parse("image/*"), file));
}
RequestBody body = builder.build();
Call<ResponseBody> call = service.upFile(body);
    ...

可以上传json数据

@POST("/uploadJson")
Call<ResponseBody> postJson(@Body RequestBody jsonBody);
 RequestBody body= 
               RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"), jsonString);
 Call<ResponseBody> call = APIService.postJson(requestBody);
    ...

Converter

默认情况下,Retrofit只能将HTTP请求体反序列化为OkHttp的ResponseBody类型,它只能接受它的RequestBody类型,
但是实际应用中会根据项目需求规定要转换的响应体类型,这时就需要添加转换器来支持其他类型,官方提供了六个序列化库,方便大家使用;

实际中Gson的序列化库是最常用的:
首先添加依赖:compile 'com.squareup.retrofit2:converter-gson:2.0.2'

通过GsonConverterFactory为Retrofit添加Gson支持:

Retrofit retrofit = new Retrofit.Builder()
      .baseUrl(url)
      .addConverterFactory(GsonConverterFactory.create(gson))
      .build();

根据json结构生成实体bean类(ApiBeans),也就是请求的响应体类型

public interface ApiService {
  @GET("api/public")
  Call<ApiBeans> getData();
}

CallAdapter

retrofitrxjava的结合使用就是同CallAdapter来实现的

首先导入依赖:

compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'

通过RxJavaCallAdapterFactory为Retrofit添加RxJava 2支持:

Retrofit retrofit = new Retrofit.Builder()
      .baseUrl(url)
      .addConverterFactory(GsonConverterFactory.create())
      .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) 
      .build();

retrofit 可以提供多个CallAdapter,比如同时添加rxjava 1的支持,但也需要导入rxjava 1 的依赖和通过RxJavaCallAdapterFactory为Retrofit添加RxJava 1支持。

对于retrofit的学习才刚刚开始!
retrofit :入门
retrofit :Json数据缓存
retrofit :文件断点下载

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容