本文是为学习大佬Carson_Ho的一篇关于Retrofit的博客,如有错误,还请各位看官指正。
这是金山词霸的一个翻译api
接口地址:http://fy.iciba.com/ajax.php?a=fy&f=auto&t=auto&w=hello%20world
参数说明:
a:固定值 fy
f:原文内容类型,日语取 ja,中文取 zh,英语取 en,韩语取 ko,德语取 de,西班牙语取 es,法语取 fr,自动则取 auto
t:译文内容类型,日语取 ja,中文取 zh,英语取 en,韩语取 ko,德语取 de,西班牙语取 es,法语取 fr,自动则取 auto
w:查询内容
在模块gradle文件的dependencies中加入
implementation 'com.squareup.retrofit2:retrofit:2.0.2'
在menifest文件中加入网络权限。
<uses-permission android:name="android.permission.INTERNET"/>
如果是安卓9.0及以上系统,还需要在application标签下加入 useClearTextTraffic = true属性。
public class Translation {
private int status;
private content content;
private static class content {
private String from; //原文语种
private String to; //译文语种
private String vendor; //来源平台
private String out; //译文内容
private int errNo; //错误码,0为正确返回
}
public String getTranslation() {
return status + " " + content.from + " " + content.to + " " + content.vendor + " "
+ content.out + " " + content.errNo;
}
}
public interface TranslateService {
@GET("ajax.php?a=fy&f=auto&t=auto&w=hello Retrofit")
Call<Translation> getInfo(); //接收网络请求数据的方法,泛型为创建的对应的bean类
}
注意:在retrofit中,请求完整的Url = 创建实例时baseUrl中的字符串 + 注解中的字符串合起来表示的地址,如下图所示:
注意:
上图中baseUrl可以不设置有误,必须指定,否则运行时会报错。baseUrl方法末尾和接口注解开头的 ‘/’,它们加与不加都是有区别的。习惯上使用上面第三种方式。
//创建Retrofit实例
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://fy.iciba.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
//通过Retrofit实例创建接口实例
TranslateService service = retrofit.create(TranslateService.class);
//将请求封装成Call对象
Call<Translation> call = service.getInfo();
//进行异步请求
button.setOnClickListener(v -> call.enqueue(new Callback<Translation>() {
@Override
public void onResponse(Call<Translation> call, Response<Translation> response) {
assert response.body() != null;
textView.setText(response.body().getTranslation());
Log.d("ttw", "response:" + response.body().getTranslation());
}
@Override
public void onFailure(Call<Translation> call, Throwable t) {
Log.d("ttw", "请求失败 ");
}
}));
在创建请求接口时,还有许多其他注解类型可以根据需求选用:
这些注解分别对应Http中的网络请求方式,这里顺便说说这些对应的Http中的网络请求方式:
GET:取得服务器上的某一资源或数据。
POST:向服务器提交数据。这个方法用途广泛,几乎目前所有的提交操作都是靠这个完成。
HEAD:与get方法类似,但不返回message body内容,仅仅是获得获取资源的请求头对应的部分信息。
PUT:用于创建和更新资源或数据。
DELETE:删除某一个资源,使用比较少见。
常用的就是@GET和@POST请求
作用:替换@GET、@POST、@PUT、@DELETE、@HEAD 注解的作用 及更多功能拓展
public interface NewsService {
/**
* method:网络请求的方法(区分大小写)
* path:网络请求地址路径
* hasBody:是否有请求体
*/
@HTTP(method = "GET", path = "blog/{id}", hasBody = false)
Call<ResponseBody> getCall(@Path("id") int id);
// {id} 表示是一个变量
// method 的值 retrofit 不会做处理,所以要自行保证准确
}
作用:表示发送form-encoded的数据
使用时每个键值对需要用@Filed来注解键名,后面的参数是对应的值,注意键和值中间没有逗号。调用请求方法时需要传递对应的参数。通常@POST和@FormUrlEncoded一起使用。
@POST("/form")
@FormUrlEncoded
Call<ResponseBody> login(@Field("name") String name, @Field("age") int age);
//2.也可以用FieldMap提交一个map,需要用@FieldMap修饰Map,这个注解会在下面说到。在创建Call的实例之前需要先创建Map对象,然后将它作为参数传入。
@FormUrlEncoded
@POST("/form")
Call<User> login(@FieldMap Map<String, int> formMap);
//3.也可以把整个表单封装为一个实体,使用@Body一次提交。这个@Body的用法在下面的网络请求参数中说明
@FormUrlEncoded
@POST("/form")
Call<User> login(@Body User user);
使用时每个键值对需要用@Part来注解键名,它可以修饰三种类型:RequestBody,okhttp3.MultipartBody.Part,任意除okhttp3.MultipartBody.Part 以外的类型。调用请求方法时需要传递对应的参数。
@Multipart
@POST("/form")
Call<ResponseBody> testFileUpload1(@Part("name") RequestBody name, @Part("age") RequestBody age, @Part MultipartBody.Part file);
//与其他请求方式不同的是,在创建Call对象前,需要先创建相应类型的参数,如下所示:
RequestBody name = RequestBody.create(textType, "Carson");
RequestBody age = RequestBody.create(textType, "24");
MultipartBody.Part filePart = MultipartBody.Part.createFormData("file", "test.txt", file);
Call<ResponseBody> call3 = service.testFileUpload1(name, age, filePart);
作用:表示返回的数据以流的形式返回,场用于大文件传输的场景
注意:大文件官方建议用 @Streaming 来进行注解,不然会出现IO异常,小文件可以忽略不注入。如果想进行断点续传的话 可以在此加入header
public interface MyService {
@Streaming
@GET
Observable<ResponseBody> download(@Url String Url, @Header("RANGE"), String range);
}
//不固定请求头
@GET("user")
Call<User> getUser(@Header("Authorization") String authorization)
//固定请求头
@Headers("Authorization: authorization")
@GET("user")
Call<User> getUser()
// 以上的效果是一致的。
// 区别在于使用场景和使用方式
// 1. 使用场景:@Header用于添加不固定的请求头,@Headers用于添加固定的请求头
// 2. 使用方式:@Header作用于方法的参数;@Headers作用于方法
作用:以 Post方式 传递 自定义数据类型 给服务器
特别注意:如果提交的是一个Map,那么作用相当于 @Field
不过Map要经过 FormBody.Builder 类处理成为符合 Okhttp 格式的表单,如:
FormBody.Builder builder = new FormBody.Builder();
builder.add("key","value");
在上面@FormUrlEncoded注解中举过例,表明发送Post请求时提交键值对或Map对象,与@FormUrlEncoded配合使用。
与 @Multipart 注解配合使用,发送 Post请求时提交请求的表单字段,在上文@Multipart中有过例子。
作用:用于 @GET 方法的查询参数(Query = Url 中 ‘?’ 后面的 key-value)
如:url = http://www.println.net/?cate=android,其中,Query = cate
具体使用:配置时只需要在接口方法中增加一个参数即可:
@GET("/")
Call<String> cate(@Query("cate") String cate);
作用:URL地址的缺省值
具体使用:
public interface GetRequest_Interface {
@GET("users/{user}/repos")
Call<ResponseBody> getBlog(@Path("user") String user );
// 访问的API是:https://api.github.com/users/{user}/repos
// 在发起请求时, {user} 会被替换为方法的第一个参数 user(被@Path注解作用)
}
作用:直接传入一个请求的 URL变量 用于URL设置
具体使用:
public interface GetRequest_Interface {
@GET
Call<ResponseBody> testUrlAndQuery(@Url String url, @Query("showAll") boolean showAll);
// 当有URL注解时,@GET传入的URL就可以省略
// 当GET、POST...HTTP等方法中没有设置Url时,则必须使用 {@link Url}提供
}
在上文创建Retrofit实例的代码中有一行
addConverterFactory(GsonConverterFactory.create())
这行代码为Retrofit对象增加了数据解析器。
在使用相应的数据解析器前需要添加相应的依赖,将其中的(insert latest version)替换为最新版本,目前的 latest version 应该都是2.7.2
数据解析器 | Gradle依赖 |
---|---|
Gson | com.squareup.retrofit2:converter-gson:(insert latest version) |
Jackson | com.squareup.retrofit2:converter-jackson:(insert latest version) |
Simple XML | com.squareup.retrofit2:converter-simplexml:(insert latest version) |
Protobuf | com.squareup.retrofit2:converter-protobuf:(insert latest version) |
Moshi | com.squareup.retrofit2:converter-moshi:(insert latest version) |
Wire | com.squareup.retrofit2:converter-wire:(insert latest version) |
Scalars | com.squareup.retrofit2:converter-scalars:(insert latest version) |
在创建Retrofit请求时,可以添加如下这行代码,参数传入需要的请求适配器。同样的,使用前需要导入相应的依赖。如果不加这行代码,则使用安卓默认的请求适配器,并且不需要导入依赖。
addCallAdapterFactory(RxJavaCallAdapterFactory.create())
网络请求适配器 | Gradle依赖 |
---|---|
guava | com.squareup.retrofit2:adapter-guava:(insert latest version) |
Java8 | com.squareup.retrofit2:adapter-java8:(insert latest version) |
rxjava | com.squareup.retrofit2:adapter-rxjava:(insert latest version) |
这是一份很详细的 Retrofit 2.0 使用教程