Retrofit是由Square公司开发的类型安全HTTP客户端框架,借助动态代理在运行时生成接口实现类,将注解转化为OkHttp请求配置;节省成本通过转换器(Gson/Moshi)自动序列化JSON/XML,内部处理网络请求在主线程返回报文。Retrofit 直译是封装、翻版。他就是对okhttp做了进一步封装,方便使用,它底层的所有请求默认走的都是Okhttp。 所以使用Retrofit必须依赖okHttp。
两者区别:Retrofit是基于App发请求的封装,也就是面向的应用层(比如响应数据的处理和错误处理等),而Okhhtp是对底层网络请求的封装与优化(socket优化,数据压缩,buffer缓存等)。
本文将通过GET/POSTde 基础请求、文件上传、动态URL、缓存、转换器,以及借助OKHttp实现Retrofit请求过程中设置请求头、cookie、超时时间和拦截器都是借助OkHttpClient 等。
使用Retrofit添加的依赖,另外,使用转换器也需要在build.gradle中单独引入,两种转换器通常不必同时使用,根据项目JSON处理需求选择其一即可:
dependencies {
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
}
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.google.code.gson:gson:2.8.8'
implementation 'com.squareup.retrofit2:converter-moshi:2.9.0'
implementation 'com.squareup.moshi:moshi:1.14.0' // Moshi
先定义一个接口:
切记这里必须是interface!!!
public interface RequestService {
@GET("login/{id}")
Call login(@Path("id") int userId);
@POST("users/new")
@Headers("Content-Type: application/json") // 设置请求头
Call loginPost(@Body LoginInfo loginInfo); // @Body注解表示请求体
@Multipart // 表示多部分请求
@POST("upload")
Call uploadFile( @Part("description") RequestBody description, @Part MultipartBody.Part file);
// 借助@Url注解,指定完整URL
@GET
Call getCustomUrl(@Url String url);
//借助Query注解,添加查询参数
@GET("search")
Call queryData(@Query("q") String query);
}
定义实体类 LoginInfo.java :
public class LoginInfo {
private String userNmae;
private String userPwd;
public LoginInfo(String userNmae, String userPwd) {
this.userNmae = userNmae;
this.userPwd = userPwd;
}
}
定义初始化Retrofit的单例工具类 RetrofitUtil.java :
public class RetrofitUtil {
private static RetrofitUtil retrofitUtil;
private Retrofit retrofit;
File httpCacheDirectory = new File(BaseApplication.getContext().getCacheDir(), "responses");
int cacheSize = 10 * 1024 * 1024; // 10MB
Cache cache = new Cache(httpCacheDirectory, cacheSize);
private RetrofitUtil(){
}
public static RetrofitUtil getInstance(){
synchronized (RetrofitUtil.class){
if (retrofitUtil == null){
retrofitUtil = new RetrofitUtil();
}
return retrofitUtil;
}
}
public T getServer(Class cls, String baseUrl){
if (retrofit == null){
retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.client(getClient())
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit.create(cls);
}
public OkHttpClient getClient(){
// 创建OkHttpClient
OkHttpClient okHttpClient = new OkHttpClient.Builder()
// .cookieJar()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(10, TimeUnit.SECONDS)
.writeTimeout(10, TimeUnit.SECONDS)
.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
// 添加统一请求头
request = request.newBuilder()
.header("Cache-Control", "public, max-age=60")
.build();
return chain.proceed(request);
}
})
.cache(cache)
.build();
return okHttpClient;
}
}
注意Retrofit在设置请求头、cookie、超时时间和拦截器都是借助OkHttpClient 来实现。
getTv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int id = 600001;
RetrofitUtil.getInstance().getServer(RequestService.class,mUrl).login(id).enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
if (response.isSuccessful()) {
LoginInfo loginInfo = response.body(); // 自动解析JSON为User对象
}
}
@Override
public void onFailure(Call call, Throwable t) {
t.printStackTrace();
}
});
}
});
LoginInfo loginInfo = new LoginInfo("Admin", "12345678");
// 发起请求
Call call = RetrofitUtil.getInstance().getServer(RequestService.class,mUrl).loginPost(loginInfo);
call.enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
// 请求成功
}
@Override
public void onFailure(Call call, Throwable t) {
// 请求失败
}
});
// 准备文件
File file = new File("path/to/file.jpg");
RequestBody requestFile = RequestBody.create(MediaType.parse("image/jpeg"), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getName(), requestFile);
// 发起上传请求
RetrofitUtil.getInstance().getServer(RequestService.class,mUrl).uploadFile(
RequestBody.create(MediaType.parse("text/plain"), "文件描述"),
body).enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
//处理上传成功后的逻辑
}
@Override
public void onFailure(Call call, Throwable t) {
//处理上传失败的逻辑
}
});
2.4动态指定URL和添加查询参数
一般来说一个项目中你可能定封装了公共个请求路径和域名,但有个别接口就需要特立独行的地址和传参,此时可以借助@Url和@Query动态的实现。 两个请求也在上面给出的RequestService 这个接口中定义了。
// 使用动态URL
Call call1 = RetrofitUtil.getInstance().getServer(RequestService.class,mUrl).getCustomUrl("https://api.example.com/custom/path");
// 使用查询参数
Call call2 = RetrofitUtil.getInstance().getServer(RequestService.class,mUrl).queryData("retrofit");
个人总结记录,才疏学浅,如有错误,欢迎指正,多谢。