Retrofit底层基于OkHttp实现,使用运行时注解提供功能,本文主要内容为其基本使用
build.gradle配置
Java8支持
android {
......
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}
}
依赖
//添加retrofit
implementation 'com.squareup.retrofit2:retrofit:2.7.0'
//添加gson解析 平时用的基本都是返回值为Gson类型数据,故添加此依赖
//若想用其他类型数据 自行添加
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
AndroidManifest.xml添加网络权限
<uses-permission android:name="android.permission.INTERNET"/>
Retrofit的注解分为三大类,分别是HTTP请求方法注解、标记类注解和参数类注解。HTTP注解有8种,即GET、POST这些,标记类注解有3种,FormUrlEncoded、Multipart、Streaming。下载文件时建议使用Streaming注解。参数类注解有有Header、Headers、Body、Path、Field、FieldMap、Part、PartMap、Query和QueryMap等。
HTTP注解之GET请求
HTTP注解为GET
参数类注解主要为Query
、QueryMap
简单请求接口 @Query
当参数较少时可以使用该注解
public interface GetRequest {
@GET("s")//请求方法注解 接口使用百度搜索,只需wd参数即可
Call<ResponseBody> getCall(@Query("wd") String wd);
}
Retrofit默认将String转换成Json obj,如果不需要gson转换,那么就指定泛型为ResponseBody,且不要设置gson转换器
动态配置URL @Path
该注解支持任何HTTP请求
上面的代码可改为:
public interface GetRequest {
@GET("{path}")//此处的path会被参数path替换
Call<ResponseBody> getCall(
@Path("path") String path,
@Query("wd") String wd);
}
查询条件组 @QueryMap
当有多个请求参数时可以考虑使用该注解
上面的代码可改为:
public interface GetRequest {
@GET("{path}")
Call<ResponseBody> getCall(
@path("path") String path,
@QueryMap Map<String, String> parameter);
}
创建Retrofit
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://www.baidu.com/")
.build();
//实际Url = baseUrl + 请求接口的Url
//即 "https://www.baidu.com/wd=Android"
Retrofit动态代理获取到定义的接口
GetRequest getRequest = retrofit.create(GetRequest.class);
返回Call对象
//百度搜索Android
Call<ResponseBody> call = getRequest.getCall("Android");
异步调用(该回调运行于UI线程)
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
Log.d(TAG,response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.e(TAG,t.getMessage()+"");
}
});
同步调用
call.enecute(xxx);
中断请求
call.cancel();
看起来貌似和OkHttp差不多,做一个小例子
GET请求例子
请求使用的接口为免费天气API接口
@GET("{path}")
Call<WeatherBean> getCall(
@Path("path") String path,
@QueryMap Map<String, String> map);
private void queryMap(){
Map<String, String> ks = new HashMap<>();
ks.put("version","v1");
ks.put("appsecret","你的appsecret");
ks.put("appid","你的appid");
ks.put("city","欲查询地区");
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://www.tianqiapi.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
retrofit.create(GetRequest.class)
.getCall("api",ks)
.enqueue(new Callback<WeatherBean>() {
@Override
public void onResponse(Call<WeatherBean> call, Response<WeatherBean> response) {
Log.d(TAG,response.body().getUpdate_time());
}
@Override
public void onFailure(Call<WeatherBean> call, Throwable t) {
Log.e(TAG,t.getMessage());
}
});
}
HTTP注解之POST请求
HTTP注解为POST
标记类注解主要为FormUrlEncoded
参数类注解主要为Field
、FieldMap
如果服务器支持Json字符串参数,参数类注解也可以使用Body
请求流程与GET基本一致,直接上例子
POST请求例子
简单使用(使用接口为开源社区登录接口)
参数 | 类型 | 必填 |
---|---|---|
name | String | 是 |
passwd | String | 是 |
接口请求返回结果如下
{
"code": 200,
"message": "成功!",
"result": {
"apikey": "xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"email": "xxxxxxxxxx@qq.com"
}
}
两种请求接口方式
方式一
@FormUrlEncoded
@POST("developerLogin")
Call<K> login(@Field("name") String name,
@Field("passwd") String pwd);
如果参数为表单则需要加上@FormUrlEncoded
,忘记添加则报错:
@Field parameters can only be used with form encoding.
方式二
@POST("developerLogin")
Call<K> login(@Query("name") String name,
@Query("passwd") String pwd);
GET和POST参数都可以使用@Query
注解
请求方法
private void login(){
String name = username.getText().toString().trim();
String pwd = password.getText().toString().trim();
if (!TextUtils.isEmpty(name) && !TextUtils.isEmpty(pwd)){
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.apiopen.top/")
.addConverterFactory(GsonConverterFactory.create())
.build();
retrofit.create(GetRequest.class)
.login(name, pwd)
.enqueue(new Callback<K>() {
@Override
public void onResponse(Call<K> call, Response<K> response) {
Log.i(TAG,response.body().getResult().getApikey());
}
@Override
public void onFailure(Call<K> call, Throwable t) {
Log.e(TAG,t.getMessage());
}
});
}
}
待完善