Retrofit2 官网提供的示例代码并不完善,想要本地跑一下看下效果都不行。

总的来说,在写过 okhttp3 和 retrofit2 之后,不得不承认后者更加方便,不需要手动解析为 json 数据了,通过注解提供统一的 restful 接口。当然,对于新手,可以先忽略这些话语,第一步还是学会怎么用。

一、怎么用

1. 引入依赖

修改 app/build.gradle 文件,引入 retrofit2 的依赖包,其中 converter-gson 包用于将网络请求返回数据解析为 json 格式。

  1. implementation 'com.squareup.retrofit2:retrofit:2.5.0'
  2. implementation 'com.squareup.retrofit2:converter-gson:2.5.0'

2. 添加网络权限

修改 app/src/main/AndroidManifest.xml 文件,添加网络权限。网络请求自然需要网络权限,感觉这句话好傻逼~

  1. <uses-permission android:name="android.permission.INTERNET"/>

3. 定义实体类

首先看一下网络请求返回数据,是个 json 格式,如下。我们需要定义一个实体类,数据结构与 json 结构一致,这样 retrofit2 会自动帮助我们将 json 数据解析成 java 实体类。

  1. {
  2. "code": "0000",
  3. "message": "操作成功",
  4. "data": [{
  5. "id": 22,
  6. "user_id": 9,
  7. "author_name": "七品",
  8. "book_name": "兵者",
  9. "book_desc": "",
  10. "book_cover_url": "https://novel.dkvirus.top/images/cover.png",
  11. "recent_chapter_url": "https://www.biquge5200.cc/98_98081/160878627.html",
  12. "last_update_at": "2018-12-14T02:31:46.000Z"
  13. }, {
  14. "id": 23,
  15. "user_id": 9,
  16. "author_name": "九灯和善",
  17. "book_name": "超品巫师",
  18. "book_desc": "",
  19. "book_cover_url": "https://novel.dkvirus.top/images/cover.png",
  20. "recent_chapter_url": "https://www.biquge5200.cc/84_84888/154804872.html",
  21. "last_update_at": "2018-12-14T02:31:46.000Z"
  22. }]
  23. }

实体类,其中 data 属性是个列表类型(js里叫做数组),列表中每一项又可以作为一个子类。

  1. package top.dkvirus.novel.retrofit2test;
  2. import com.google.gson.annotations.SerializedName;
  3. import java.util.List;
  4. public class Shelf{
  5. private String code;
  6. private String message;
  7. private List<ShelfVo> data;
  8. class ShelfVo {
  9. private int id;
  10. @SerializedName("user_id")
  11. private int userId;
  12. @SerializedName("author_name")
  13. private String authorName;
  14. @SerializedName("book_name")
  15. private String bookName;
  16. @SerializedName("book_desc")
  17. private String bookDesc;
  18. @SerializedName("book_cover_url")
  19. private String bookCoverUrl;
  20. @SerializedName("recent_chapter_url")
  21. private String recentChapterUrl;
  22. // get/set 方法,自行添加
  23. }
  24. // get/set 方法,自行添加
  25. }

上面代码可以看到用到了一个注解 @SerializedName,网络请求返回的数据结构字段命名用下划线分隔的,如:book_name,但是在 Java 里命名风格是驼峰规则,即 bookName,为了适应这样转变,添加该注解。

4. 定义服务接口

  1. package top.dkvirus.novel.retrofit2test;
  2. import retrofit2.Call;
  3. import retrofit2.Retrofit;
  4. import retrofit2.converter.gson.GsonConverterFactory;
  5. import retrofit2.http.GET;
  6. import retrofit2.http.Query;
  7. public interface NovelService {
  8. @GET("gysw/novel/classify")
  9. Call<Classify> getClassify();
  10. @GET("gysw/shelf")
  11. Call<Shelf> getShelf(@Query("user_id") int userId);
  12. public static final Retrofit retrofit = new Retrofit.Builder()
  13. .baseUrl("https://novel.dkvirus.top/api/test/")
  14. .addConverterFactory(GsonConverterFactory.create())
  15. .build();
  16. }

上面代码提供了两个接口。一定要注意接口方法 Url 前面不能有斜线。@GET(“gysw/novel/classify”) 是正确的,但是 @GET(“/gysw/novel/classify”) 是错误的。

5. 使用

在需要调用网络结构的地方直接调用即可,下面代码为异步请求示例代码。

  1. NovelService novelService = NovelService.retrofit.create(NovelService.class);
  2. Call<Shelf> call = novelService.getShelf(9);
  3. call.enqueue(new Callback<Shelf>() {
  4. @Override
  5. public void onResponse(Call<Shelf> call, final Response<Shelf> response) {
  6. Log.d("Test", "onResponse: 网络请求成功");
  7. }
  8. @Override
  9. public void onFailure(Call<Shelf> call, Throwable t) {
  10. Log.d("Test", "onFailure: 网络请求失败");
  11. }
  12. });

二、更多

1. 打印日志

1)为啥要打印日志

首先要搞清楚为什么要打印日志,日志都打印什么东东。

网络请求,难免会出错,这个时候就想要定位是什么问题,日志可以帮助我们定位。

日志有哪些东东?无非就是请求了什么,响应了什么,看一看请求的 url 地址和 method 有没有问题,看一看响应的数据结构有没有问题,这一切在 retrofit2 中可以通过简单配置做到。

2)怎么打印日志

检查 src/build.gradle 文件是否有以下依赖,没有的话自行补充。

  1. // Retrofit2
  2. implementation 'com.squareup.retrofit2:retrofit:2.5.0'
  3. implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
  4. implementation 'com.squareup.okhttp3:logging-interceptor:3.6.0'

新建一个类 HttpUtil.java,可以看到 12-21 都是处理日志相关代码,静态方法最终返回 retrofit 对象。

  1. package top.dkvirus.novel.retrofit2test;
  2. import okhttp3.OkHttpClient;
  3. import okhttp3.logging.HttpLoggingInterceptor;
  4. import retrofit2.Retrofit;
  5. import retrofit2.converter.gson.GsonConverterFactory;
  6. public class HttpUtil {
  7. public static Retrofit getRetrofit () {
  8. // 处理日志
  9. OkHttpClient.Builder client = new OkHttpClient.Builder();
  10. HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
  11. // 生产/开发环境自动切换日志模式
  12. if (BuildConfig.DEBUG) {
  13. logging.setLevel(HttpLoggingInterceptor.Level.BODY);
  14. } else {
  15. logging.setLevel(HttpLoggingInterceptor.Level.BASIC);
  16. }
  17. client.addInterceptor(logging);
  18. Retrofit retrofit = new Retrofit.Builder()
  19. .baseUrl("https://novel.dkvirus.top/api/test/")
  20. .addConverterFactory(GsonConverterFactory.create())
  21. .client(client.build())
  22. .build();
  23. return retrofit;
  24. }
  25. }

3)实际使用

实际使用跟第一部分第5小点介绍的一样,只不过 retrofit 对象从 HttpUtil 中获取了。

4)打印日志截图

网络请求之Retrofit2 - 图1

  • 第一个红框可以看到请求方法(GET),请求地址等信息;

  • 第二个红框可以看到 200ok 说明此次网络请求成功了;

  • 第三方红框可以看到响应的头信息以及响应体的 json 数据(红框最下面)。

2. 统一处理请求头

3. 注解

这篇文章注解介绍的很详细。

https://blog.csdn.net/itachi85/article/details/53007262