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 :文件断点下载

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342

推荐阅读更多精彩内容