Retrofit2 官网提供的示例代码并不完善,想要本地跑一下看下效果都不行。
总的来说,在写过 okhttp3 和 retrofit2 之后,不得不承认后者更加方便,不需要手动解析为 json 数据了,通过注解提供统一的 restful 接口。当然,对于新手,可以先忽略这些话语,第一步还是学会怎么用。
一、怎么用
1. 引入依赖
修改 app/build.gradle 文件,引入 retrofit2 的依赖包,其中 converter-gson 包用于将网络请求返回数据解析为 json 格式。
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
2. 添加网络权限
修改 app/src/main/AndroidManifest.xml 文件,添加网络权限。网络请求自然需要网络权限,感觉这句话好傻逼~
<uses-permission android:name="android.permission.INTERNET"/>
3. 定义实体类
首先看一下网络请求返回数据,是个 json 格式,如下。我们需要定义一个实体类,数据结构与 json 结构一致,这样 retrofit2 会自动帮助我们将 json 数据解析成 java 实体类。
{
"code": "0000",
"message": "操作成功",
"data": [{
"id": 22,
"user_id": 9,
"author_name": "七品",
"book_name": "兵者",
"book_desc": "",
"book_cover_url": "https://novel.dkvirus.top/images/cover.png",
"recent_chapter_url": "https://www.biquge5200.cc/98_98081/160878627.html",
"last_update_at": "2018-12-14T02:31:46.000Z"
}, {
"id": 23,
"user_id": 9,
"author_name": "九灯和善",
"book_name": "超品巫师",
"book_desc": "",
"book_cover_url": "https://novel.dkvirus.top/images/cover.png",
"recent_chapter_url": "https://www.biquge5200.cc/84_84888/154804872.html",
"last_update_at": "2018-12-14T02:31:46.000Z"
}]
}
实体类,其中 data 属性是个列表类型(js里叫做数组),列表中每一项又可以作为一个子类。
package top.dkvirus.novel.retrofit2test;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class Shelf{
private String code;
private String message;
private List<ShelfVo> data;
class ShelfVo {
private int id;
@SerializedName("user_id")
private int userId;
@SerializedName("author_name")
private String authorName;
@SerializedName("book_name")
private String bookName;
@SerializedName("book_desc")
private String bookDesc;
@SerializedName("book_cover_url")
private String bookCoverUrl;
@SerializedName("recent_chapter_url")
private String recentChapterUrl;
// get/set 方法,自行添加
}
// get/set 方法,自行添加
}
上面代码可以看到用到了一个注解 @SerializedName,网络请求返回的数据结构字段命名用下划线分隔的,如:book_name,但是在 Java 里命名风格是驼峰规则,即 bookName,为了适应这样转变,添加该注解。
4. 定义服务接口
package top.dkvirus.novel.retrofit2test;
import retrofit2.Call;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.http.GET;
import retrofit2.http.Query;
public interface NovelService {
@GET("gysw/novel/classify")
Call<Classify> getClassify();
@GET("gysw/shelf")
Call<Shelf> getShelf(@Query("user_id") int userId);
public static final Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://novel.dkvirus.top/api/test/")
.addConverterFactory(GsonConverterFactory.create())
.build();
}
上面代码提供了两个接口。一定要注意接口方法 Url 前面不能有斜线。@GET(“gysw/novel/classify”) 是正确的,但是 @GET(“/gysw/novel/classify”) 是错误的。
5. 使用
在需要调用网络结构的地方直接调用即可,下面代码为异步请求示例代码。
NovelService novelService = NovelService.retrofit.create(NovelService.class);
Call<Shelf> call = novelService.getShelf(9);
call.enqueue(new Callback<Shelf>() {
@Override
public void onResponse(Call<Shelf> call, final Response<Shelf> response) {
Log.d("Test", "onResponse: 网络请求成功");
}
@Override
public void onFailure(Call<Shelf> call, Throwable t) {
Log.d("Test", "onFailure: 网络请求失败");
}
});
二、更多
1. 打印日志
1)为啥要打印日志
首先要搞清楚为什么要打印日志,日志都打印什么东东。
网络请求,难免会出错,这个时候就想要定位是什么问题,日志可以帮助我们定位。
日志有哪些东东?无非就是请求了什么,响应了什么,看一看请求的 url 地址和 method 有没有问题,看一看响应的数据结构有没有问题,这一切在 retrofit2 中可以通过简单配置做到。
2)怎么打印日志
检查 src/build.gradle 文件是否有以下依赖,没有的话自行补充。
// Retrofit2
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.6.0'
新建一个类 HttpUtil.java,可以看到 12-21 都是处理日志相关代码,静态方法最终返回 retrofit 对象。
package top.dkvirus.novel.retrofit2test;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class HttpUtil {
public static Retrofit getRetrofit () {
// 处理日志
OkHttpClient.Builder client = new OkHttpClient.Builder();
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
// 生产/开发环境自动切换日志模式
if (BuildConfig.DEBUG) {
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
} else {
logging.setLevel(HttpLoggingInterceptor.Level.BASIC);
}
client.addInterceptor(logging);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://novel.dkvirus.top/api/test/")
.addConverterFactory(GsonConverterFactory.create())
.client(client.build())
.build();
return retrofit;
}
}
3)实际使用
实际使用跟第一部分第5小点介绍的一样,只不过 retrofit 对象从 HttpUtil 中获取了。
4)打印日志截图
第一个红框可以看到请求方法(GET),请求地址等信息;
第二个红框可以看到 200ok 说明此次网络请求成功了;
第三方红框可以看到响应的头信息以及响应体的 json 数据(红框最下面)。
2. 统一处理请求头
3. 注解
这篇文章注解介绍的很详细。