retrofit2

官方文档
github

快速使用

简单get

先创建一个接口
MyApi.java

1
2
3
4
public interface MyApi {
@GET("/{pa}")
Call<ResponseBody> get(@Path ("pa")String path,@Query("page")String upage, @Query("count")String ucount);
}

MainActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.apiopen.top")
.build();
Call<ResponseBody> stringvalue = retrofit.create(MyApi.class).get("getTangPoetry","1","1");
stringvalue.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
try {
Log.d(TAG, "onResponse: "+response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
//如果访问失败的调用
Log.e(TAG, "onFailure: "+"失败了",t);
}
});

表示get一个网址,网址地址是https://api.apiopen.top/getTangPoetry?page=1&count=1
这个返回的结果是一个ResponseBody类型的值,通过调用body().string()获得内容字符串

简单post

要post的是一个阿里云翻译的接口,有三个参数,s,q,s,并且需要在header中添加的值,具体内容看阿里云翻译
https://trans.xiaohuaerai.com/trans

给出的结果值是

1
2
3
4
{
"status": 200,
"msg": "你好,世界"
}

先根据结果创建一个item类
Item.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Item {
private int status;
private String msg;
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
@Override
public String toString() {
return "Item{" +"status=" + status +", msg='" + msg + '\'' +'}';
}
}

先创建一个interface,实现一个post的方法,放入参数和header

1
2
3
4
5
public interface MyApi {
@FormUrlEncoded
@POST("/trans")
Call<Item> post(@Header ("Authorization")String code,@Field("d")String d, @Field("q")String q, @Field("s")String s);
}

MainActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://trans.xiaohuaerai.com")
.addConverterFactory(GsonConverterFactory.create())
.build();
Call<Item> stringvalue = retrofit.create(MyApi.class).post("APPCODE xxxxx","zh-CN","hello","en");
stringvalue.enqueue(new Callback<Item>() {
@Override
public void onResponse(Call<Item> call, retrofit2.Response<Item> response) {
Log.d(TAG, "onResponse: "+response.body());
}
@Override
public void onFailure(Call<Item> call, Throwable t) {
//如果访问失败的调用
Log.e(TAG, "onFailure: "+"失败了",t);
}
});

注意response.body()才是格式化好的Item类
这次使用了一个GsonConverterFactory工厂直接把结果转化成Item类

搭配rxjava

先创建interface
MyApi.java

1
2
3
4
public interface MyApi {
@GET("/{pa}")
Observable<ResponseBody> get(@Path ("pa")String path, @Query("page")String upage, @Query("count")String ucount);
}

注意返回值由call变成了Observable

MainActivity.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
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.apiopen.top")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
MyApi stringvalue = retrofit.create(MyApi.class);
stringvalue.get("getTangPoetry","1","1")
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<ResponseBody>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "onSubscribe: ");
}
@Override
public void onNext(ResponseBody responseBody) {
try {
Log.d(TAG, "onNext: "+responseBody.string());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onError(Throwable e) {
Log.e(TAG, "onError: ",e );
}
@Override
public void onComplete() {
Log.d(TAG, "onComplete: ");
}
});

更多搭配rxjava的方法参考之前写的博客

解析器

上面快速使用post中用到了一个GsonConverterFactory工厂直接把结果转化成Item类

另外官方还给出了别的解析类

  • Gson: com.squareup.retrofit2:converter-gson
  • Jackson: com.squareup.retrofit2:converter-jackson
  • Moshi: com.squareup.retrofit2:converter-moshi
  • Protobuf: com.squareup.retrofit2:converter-protobuf
  • Wire: com.squareup.retrofit2:converter-wire
  • Simple XML: com.squareup.retrofit2:converter-simplexml
  • Scalars (primitives, boxed, and String): com.squareup.retrofit2:converter-scalars

自定义结果解析器

自己解析返回的结果GsonConverFactory.create,点进去这个方法,主要看responseBodyConverter方法,这个是处理返回请求的,他是调用了GsonResponseBodyConverter来处理请求,点进去这个类,public T convert(ResponseBody value)这个方法就是返回要构造的对象,参数value就是返回的response的body值,可以通过value.string();得到具体的字符串,在这个方法里解析可以通过throw的方式调用观察者的onError方法

所以重写结果解析器需要复制出来GsonConverFactory这个类,并且复制GsonResponseBodyConverter和GsonRequestBodyConverter这两个类,并且重新写一下GsonResponseBodyConverter这个类的convert方法对结果进行解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Override
public T convert(ResponseBody value) throws IOException {
String response = value.string();
Log.d("tag", "convert: " + response);
//抛出异常,通过观察者的onError回掉接收结果
if (1 == 1)
throw new JsonIOException("抛出异常");
JsonReader jsonReader = gson.newJsonReader(value.charStream());
try {
T result = adapter.read(jsonReader);
if (jsonReader.peek() != JsonToken.END_DOCUMENT) {
throw new JsonIOException("JSON document was not fully consumed.");
}
return result;
} finally {
value.close();
}
}

进阶使用

retrofit底层是使用的okhttp,所以如果要设置监听器或者设置超时,cookie等关于链接的操作可以创建一个okhttpclient,然后retrofit绑定即可

1
2
3
OkhttpClient client = new OkhttpClient.Builder().build();
Retrofit retrofit = new Retrofit.Builder().client(client)
.build();

更多retrofit的用法参考自此博客