Retrofit 2 使用指南

概述

Retrofit 是 Squareup 公司开源的网络请求框架,它其实是对 OkHttp 的一层封装,使用面向接口的方式进行网络请求,利用动态生成的代理类封装了网络接口请求的底层,并且提供了对 RxJava 的支持。
写这篇文章的时候,Retrofit 已经发布 2.3.0 了,本文就以此版本来介绍。
GitHub 地址

基本用法

添加依赖:

1

2

3
compile 'com.squareup.retrofit2:retrofit:2.3.0'

compile 'com.squareup.retrofit2:converter-gson:2.3.0'

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

注意 compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0' 是添加了对RxJava2的支持,一定要注意RxJava的版本对应问题,否则会报错:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19
Caused by: java.lang.IllegalArgumentException: Unable to create call adapter for io.reactivex.Observable<com.example.heqiang.testsomething.testretrofit.RequestManager$TestBean>

for method RequestService.getDataRx

at retrofit2.ServiceMethod$Builder.methodError(ServiceMethod.java:752)

at retrofit2.ServiceMethod$Builder.createCallAdapter(ServiceMethod.java:237)

at retrofit2.ServiceMethod$Builder.build(ServiceMethod.java:162)

at retrofit2.Retrofit.loadServiceMethod(Retrofit.java:170)

at retrofit2.Retrofit$1.invoke(Retrofit.java:147)

at java.lang.reflect.Proxy.invoke(Proxy.java:393)

at $Proxy0.getDataRx(Unknown Source)

at com.example.heqiang.testsomething.testretrofit.RequestManager.getDataRx(RequestManager.java:68)

at com.example.heqiang.testsomething.rxjava.RxJavaActivity.testRetrofitRx(RxJavaActivity.java:105)

... 11 more

Caused by: java.lang.IllegalArgumentException: Could not locate call adapter for io.reactivex.Observable<com.example.heqiang.testsomething.testretrofit.RequestManager$TestBean>.

Tried:

* retrofit2.adapter.rxjava.RxJavaCallAdapterFactory

* retrofit2.ExecutorCallAdapterFactory

at retrofit2.Retrofit.nextCallAdapter(Retrofit.java:241)

at retrofit2.Retrofit.callAdapter(Retrofit.java:205)

at retrofit2.ServiceMethod$Builder.createCallAdapter(ServiceMethod.java:235)

还有个库是 com.squareup.retrofit2:adapter-rxjava,这个是仅支持RxJava1,如果想使用 RxJava2,就要用上面的依赖。
如果需要使用 Gson 作为转换器,就需要依赖 com.squareup.retrofit2:converter-gson,如果不想使用,可以自定义,比如 FastJson 等。

先上代码:

CallBack.java

1

2

3

4
public interface CallBack<T> {

void onSuccess(T t);

void onFail(Exception e);

}

RequestService.java

1

2

3

4

5

6

7
public interface  {

("hq/urls")

Call<RequestManager.TestBean> getData();

("hq/urls")

Observable<RequestManager.TestBean> getDataRx();

}

RequestManager.java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72
public class RequestManager {

private RequestService mRequestService;

private static volatile RequestManager sInstance;

private RequestManager(Context context){

Cache cache = new Cache(new File(context.getExternalCacheDir(),"test"),100*1024*1024);

Log.e("Test", "cache dir = " + context.getExternalCacheDir());

OkHttpClient client = new OkHttpClient.Builder()

.retryOnConnectionFailure(true)

.connectTimeout(20, TimeUnit.SECONDS)

.cache(cache)

.build();

Retrofit retrofit = new Retrofit.Builder()

//这里如果不指定client,那么会生成一个默认的OkHttpClient

.client(client)

.baseUrl("http://*.*.*.*/")

.addConverterFactory(GsonConverterFactory.create())

//加入对RxJava2的支持

//.addCallAdapterFactory(RxJava2CallAdapterFactory.create())

.build();

mRequestService = retrofit.create(RequestService.class);

}

public static RequestManager getInstance(){

if(sInstance == null){

synchronized (RequestManager.class){

if(sInstance == null){

sInstance = new RequestManager();

}

}

}

return sInstance;

}

public void getData(){

Call<TestBean> call = mRequestService.getData();

// 异步请求

call.enqueue(new Callback<TestBean>() {

@Override

public void onResponse(Call<TestBean> call, Response<TestBean> response) {

Log.e("Test","onResponse = "+response.body().toString());

}

@Override

public void onFailure(Call<TestBean> call, Throwable t) {

}

});

// 同步请求

try {

Response<TestBean> response = call.execute();

} catch (IOException e) {

e.printStackTrace();

}

}

public static class TestBean{

public int  code;

public String message;

public String redirect;

public ArrayList<String> value;

@Override

public String toString() {

return "code = "+code+", message = "+message+",redirect = "+ redirect+", value="+value.toString();

}

}

}

结合RxJava和RxAndroid

在上面的代码中去掉 addCallAdapterFactory(RxJava2CallAdapterFactory.create()) 的注释,再加上定义的 Observable<RequestManager.TestBean> getDataRx() 方法,就添加了对 RxJava2 的支持。
如果需要使用 RxAndroid 还要在build.gradle中添加依赖:

1
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27
public void getDataRx(final CallBack<TestBean> callBack){

mRequestService.getDataRx().subscribeOn(Schedulers.io())

// 依赖RxAndroid

.observeOn(AndroidSchedulers.mainThread())

.subscribe(new Observer<TestBean>() {

@Override

public void onError(Throwable e) {

Log.e("Test","onError");

callBack.onFail(new Exception(e));

}

@Override

public void onComplete() {

}

@Override

public void onSubscribe(@NonNull Disposable d) {

}

@Override

public void onNext(TestBean testBean) {

Log.e("Test","onNext = "+testBean.toString());

callBack.onSuccess(testBean);

}

});

CallAdapter

CallAdapter 其实就是对 Call 的转换,上面的对 RxJava 支持时用到的 RxJava2CallAdapterFactory 其实就是 CallAdapter.Factory 的子类,当然我们也可以自定义实现一个 CallAdapter

Converter

在默认情况下 Retrofit 只支持将 HTTP 的响应体转换换为 ResponseBody,那么接口的返回值都是 Call<ResponseBody>,如果我们需要把 ResponseBody 转换成我们需要的类型就需要 Converter
Converter 就是对数据的转换,代码中 addConverterFactory(GsonConverterFactory.create()) 就是指定了 Gson 将 ResponseBody转换我们想要的类型。
显然我们也可以自定义一个 Converter,比如使用 FastJson 等。

注解的使用

请求方法

  • GET
  • POST
  • PUT
  • DELETE
  • PATCH
  • HEAD
  • OPTIONS
  • HTTP

前面 6 种都是HTTP协议请求方式,使用方法和前面例子中的类似,都接受一个字符串来和 BaseUrl 组成请求Url。
HTTP 方式是对上面 6 中的扩展,用法:

1

2
@HTTP(method = "GET", path = "blog", hasBody = false)

Call<ResponseBody> getBlog();

请求参数

  • Path
  • Query
  • QueryMap

上面三种都是一个完整Url的组成部分,Path 用在 Url 的 path 部分,Query 和 QueryMap 用在参数部分,也就是Url中的 ? 后面的部分。QueryMap 相当于多个 Query。

1

2

3
("day/{year}/{month}/{day}")

Observable<DailyDataResponse> getDailyData(

@Path("year") int year,@Path("month") int month,@Path("day") int day);
1

2

3
("day")

Call<Response> getDailyData(

@Query("year") int year,@Query("month") int month,@Query("day") int day);
1

2

3
("day")

Call<Response> getDailyData(

@QueryMap Map<String, Integer> map);
  • Field :POST请求,提交单个数据
  • FieldMap:POST请求,和@Filed作用一致,用于不确定表单参数
  • Body:POST请求,以对象的形式提交,多用于post请求发送非表单数据,比如想要以post方式传递json格式数据
1

2

3

4
@FormUrlEncoded

@POST("add2gank")

Observable<AddToGankResponse> add2Gank(@Field("url") String url, @Field("desc") String desc, @Field("who") String who,

@Field("type") String type,@Field("debug") boolean debug);
1

2
@POST("add2gank")

Call<Response> add2Gank(@Body ExtrasBean bean);
1

2

3
@FormUrlEncoded

@POST("add2gank")

void add2Gank(@FieldMap Map<String, String> map)

可以看到这里多了一个 @FormUrlEncoded 注解,如果去掉 @FromUrlEncoded 在 post 请求中使用 @Field@FieldMap,那么程序会抛出 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) 的错误异常。
如果是使用 @Body,也是不用加 @FormUrlEncoded 注解的。

  • Url:实现动态Url

前面的使用都是基于BaseUrl的,如果我们想请求不同Url时只能重新生成一个 Retrofit 实例,实际上我们还可以通过 @Url 来操作。

1

2
@GET

public Call<ResponseBody> getImage(@Url String url);

如果参数指定的 url 是一个以 http 开头的 url,那么就完全使用这个url,和前面指定的 BaseUrl 完全没有联系,如果 url 指定的只有类似 /id/name 的path,而没有指定 scheme 和 host,那么它就会用 BaseUrl 的 scheme 和 host。
这里注意 :只是用 BaseUrl 的 scheme 和 host,如果 BaseUrl 是 http://www.test.com/v/ ,那么还是会把 path 中的 v 去掉,组成 http://www.test.com/id/name

  • Header:用于在方法参数里动态添加请求头:
1
Call<ResultBean> postSayHi(@Header("city") String city);
  • Part
  • PartMap

这两个用于上传文件,与 @MultiPart 注解结合使用

1

2

3
@Multipart

@POST("test/upload")

Call<ResultBean> upload(@Part("file"; filename="launcher_icon.png") RequestBody file);

方法注解

  • FormUrlEncoded:上面已经介绍过了。
  • Headers:用于在方法添加请求头
1

2

3
@POST("test/sayHi")

@Headers("Accept-Encoding: application/json")

Call<ResultBean> postSayHi(@Body UserBean userBean, @Header("city") String city);
  • Streaming:如果您正在下载一个大文件,Retrofit2将尝试将整个文件移动到内存中。为了避免这种,我们必须向请求声明中添加一个特殊的注解
1

2

3
@Streaming

@GET

Call<ResponseBody> downloadFileByDynamicUrl(@Url String fileUrl);

原文:大专栏  Retrofit 2 使用指南

原文地址:https://www.cnblogs.com/petewell/p/11601756.html

时间: 2024-08-01 10:19:32

Retrofit 2 使用指南的相关文章

【Android实战】----从Retrofit源码分析到Java网络编程以及HTTP权威指南想到的

一.简介 接上一篇[Android实战]----基于Retrofit实现多图片/文件.图文上传中曾说非常想搞明白为什么Retrofit那么屌.最近也看了一些其源码分析的文章以及亲自查看了源码,发现其对Java网络编程及HTTP权威指南有了一个很好的诠释.一直以来,都信奉一个原则,在这个新技术日新月异的时代,如何在Java界立足,凭借的就两点: 1.基本功,包括:Java基本知识,(Java编程思想.Effective Java),Java进阶(Java虚拟机.Java设计模式).网络相关(这个时

你真的会用Gson吗?Gson使用指南(4)

原文出处: 怪盗kidou 注:此系列基于Gson 2.4. 本次文章的主要内容: TypeAdapter JsonSerializer与JsonDeserializer TypeAdapterFactory @JsonAdapter注解 TypeAdapter与 JsonSerializer.JsonDeserializer对比 TypeAdapter实例 结语 后期预告 一.TypeAdapter TypeAdapter 是Gson自2.0(源码注释上说的是2.1)开始版本提供的一个抽象类,

Retrofit

Retrofit 不算是一个网络库,它应该算是封装了 okhttp ,retrofit的最大特点就是解耦,要解耦就需要大量的设计模式,然后为我们提供了一个友好的接口的一个工具库吧. 1.创建Retrofit对象: builder 模式,外观模式(门面模式) 外观模式具有高内聚.低耦合的特性,对外提供简单统一的接口,隐蔽了子系统具体的实现.隔离变化. 在封装某些特定功能时,比如下载module,外观模式是一种很好的设计规范.即下载module与其他module通信时通过DownloadManage

Retrofit 简介 wiki 文档

简介 Type-safe HTTP client for Android and Java by Square, Inc. GitHub主页:https://github.com/square/retrofit/ WIKI    官网&简易教程 JAR包 依赖与混淆 Retrofit requires at minimum Java 7 or Android 2.3. Snapshots of the development version are available in Sonatype's

Android网络框架httplite使用指南

前言 Http请求是做Android应用开发工作几乎必须要用到的东西.做Android开发这几年,从最开始仿照网上代码自己使用apache的DefaultHttpClient封装网络请求工具类,到后面开始使用GitHub上面的一些http框架,Afinal,xUtils到Volley,AsyncHttpClient等,网上这些http框架大多都还比较易用,但是做实际业务中还是感觉到业务和界面代码与Http请求的代码还是耦合性过高,特别是在服务器接口比较多的时候.所以自己在以前的项目中也一直在尝试

金三银四,磨砺锋芒;剑指大厂,扬帆起航(最全Android开发工程师面试指南)

引言 元旦匆匆而过,2020年的春节又接踵而来,大家除了忙的提着裤子加班.年底冲冲冲外,还有着对于明年的迷茫和期待! 2019年有多少苦涩心酸,2020年就有更多幸福美好,加油,奥利给!怀着一颗积极向上的心,来面对未来每一天的挑战! 所谓"兵马未动,粮草先行",我们打响明天的战役也需要精神食粮来做后勤保障才是. 在此我整理了一份安卓开发面试指南,希望对磨砺锋芒.奋发向上的小伙伴有所帮助,祝你早日剑指大厂,扬帆起航,奥利给! Java基础 Java集合框架 Java集合--ArrayLi

最全解析如何正确学习JavaScript指南,必看!

划重点 鉴于时不时,有同学私信问我:怎么学前端的问题.这里统一回复一下,如下次再遇到问我此问题同学,就直接把本文链接地址发给你了. "前端怎么学"应该因人而异,别人的方法未必适合自己.就说说我的学习方法吧:我把大部分时间放在学习js上了.因为这个js的学习曲线,先平后陡.项目实践和练习啥的,我不说了,主要说下工作之外的时间利用问题.我是怎么学的呢,看书,分析源码.个人这几天统计了一下,前端书籍目前看了50多本吧,大部分都是js的.市面上的书基本,差不多都看过. 第一个问题:看书有啥好处

微信Android接入指南

注:本文为微信Android终端开发工具的新手使用教程,只涉及教授SDK的使用方法,默认读者已经熟悉IDE的基本使用方法(本文以Eclipse为例),以及具有一定的编程知识基础等. 1.申请你的AppID 请到 开发者应用登记页面 进行登记,登记并选择移动应用进行设置后,将该应用提交审核,只有审核通过的应用才能进行开发. 2.下载微信终端开发工具包 开发工具包主要包含3部分内容:(其中,只有libammsdk.jar是必须的) - libammsdk.jar(每个第三方应用必须要导入该sdk库,

【资源共享】Rockchip I2C 开发指南 V1.0

2C设备的设备应用非常广泛,常见的包含重力传感器,触摸屏驱动芯片,音频解码等 这个文档是RK3399的I2C开发文档:<Rockchip I2C 开发指南 V1.0> 内容预览: 下载地址:http://developer.t-firefly.com/thread-12495-1-1.html