Retrofit 是Square开发的网络服务库
可以 将基于Http协议的API返回的返回的数据转化为Java对象方便操作来方便我们操作
public interface NetService {
@GET("server/{param}/api") //以Get 的方式 请求 url(server/{param}/api) >>>>注意这里的url一般来说并不是完整的url,而是全部url的后面一部分 ,一般来说还有一个BASE_URL>稍后介绍
//其中 以 { } 包围的部分是一个不定参数 >>由下面 以@Path标注的 以("")包围的参数指定
//注意,这两个的名称要一致 {param} ->("param")
//这是个方法 返回值是一个Call里面包含是一个List集合,集合里面装的是Person数据
//我们很容易猜出Call是 Retrofit在做请求/响应处理的一个封装
Call<List<Person>> getPerson(@Path("param") String name);
}
我们在这里简单提一下 Call的概念,虽然简单,但是Call是一个很重要的概念.
通过调用Retrofit2的execute(同步)或者enqueue(异步)方法,
发送请求到网络服务器,并返回一个响应(Response)。
到这里我们的接口已经定义好了>>我们来看如何使用这个接口
//去创建一个Retrofit 实例 由Retrofit实例来生成一个我们的接口实例
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://www.tp.com/") //很明显这里指定了base_url
.build();
//创建一个我们的接口实例
NetService service = retrofit.create(NetService .class);
//有了实例之后我么就可以直接调用我们定义的方法 来获取数据 并返回我们的所需
Call<List<Person>> personsCall = service.getPerson("mike");
我们再去调用相应的方法 去执行 同步或者是异步
personsCall .enqueue(new Callback<List<Person>>() { //异步请求 有一个回调接口
@Override
public void onResponse(Response<List<Person>> response, Retrofit retrofit) {
List<Person> userList = response.body(); //这就是我们要的数据
}
@Override
public void onFailure(Throwable t) {
}
});
/************************************************************/
try {
Response<List<Person>> response = personsCall .execute(); //同步请求 直接返回相应数据
List<Person> pers= response.body();
} catch (IOException e) {
e.printStackTrace();
}
Retrofit主要是采用注解的方式来描述我们的Http请求:
1.支持请求的url的地址中的不定参数指定以及查询参数的指定(这一点我们稍后说)
2.支持将对象转换成请求体(JSON,protocol buffers等等)
protocol buffers是Google公司开发的一种数据描述语言,类似于XML能够将结构化数据序列化,可用于数据存储、通信协议等方面。现阶段支持C++、JAVA、Python等三种编程语言。不必深究就是和JSON类似的一种东西
3.支持Multipart的请求体以及文件上传、
在定义一个请求接口的时候,方法上的注解和参数表明我们去怎样去执行这个请求
//每一个接口都必须使用HTTP注解,我们在注解中指明**请求方式和访问的相对地址**
// 目前支持的请求方式有五种 GET, POST, PUT, DELETE, HEAD
@GET("server/list") //请求方式 get,请求的相对地址 server/list
//当然我们也可以在我们的相对地址上携带请求参数,
@GET("server/list?id=1213")
请求地址url的操作
//前面我就提到了注解上写的请求的相对地址中放置的参数我么是可以去动态指定
//还有一点 我们也可以指定查询参数 >>查询参数是什么呢?我解释一下
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @Query("sort") String sort);
请求参数:
请求体头部信息设置
在我们定义一个请求方式之前我们也可以镜头的设置我们请求体的头部信息
@Headers("Cache-Control: max-age=640000")
@GET("widget/list")
Call<List<Widget>> widgetList();
@Headers({
"Accept: application/vnd.github.v3.full+json",
"User-Agent: Retrofit-Sample-App"
})
@GET("users/{username}")
Call<User> getUser(@Path("username") String username);
//注意 所有的头部信息不会相互覆盖 ,所有具有相同名称的头部信息会被一起加入到请求中
//一个请求体的头部信息也是可以通过@Header注解动态去改变的
@GET("user")
Call<User> getUser(@Header("Authorization") String authorization)
//注意 @Header注解中指定的参数名称必须正确,
//如果没有传入数据(authorization==null),那么头部就会被省略掉,否则就会调用参数(authorization)的toString方法转成String类型,设置到对应参数("Authorization")上
//如果所有的请求都需要指定一个头部信息,我们可以通过OkHttp interceptor.去指定
同步和异步
每一个接口实例都都可以异步或者同步的执行,每一个实例只能使用一次,但是我们可以通过克隆(调用 clone())创建一个新的实例,也可以使用
在Android中,请求的回调接口会在Android主线程中执行
在普通的Java程序中,回调和执行Http请求的线程是统一线程
Retrofit默认的设置已经比较健全的向我们提供一些列可以使用的方法,但是我们也可以自定义,这里我们不做叙述。
数据转换
默认情况下,Retrofit只能将Http的信息体转换成OKHttp的响应体ResponseBody的类型,也只支持OkHttp类型的请求体RequestBody
下面介绍六种比较常用的其它转换类型
Gson: com.squareup.retrofit2:converter-gson
Jackson: com.squareup.retrofit2:converter-jackson
Moshi: com.squareup.retrofit2:converter-moshi
Protobuf: com.squareup.retrofit2:converter-protobuf
Wire: com.squareup.retrofit2:converter-wire
Simple XML: com.squareup.retrofit2:converter-simplexml
Scalars (primitives, boxed, and String): com.squareup.retrofit2:converter-scalars
我们来懒一下比较常用的JSON类型的数据
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com")
.addConverterFactory(GsonConverterFactory.create())
//这一句就可以让数据支持JSON类型
.build();
我们可以自定义转换类型 只需要我们去继承自 Converter.Factory类 定制我们自己的转换方法即可
以上我们只了解了Retrofit的大概原理,在实际应用中没什么用 ,
我们接下来看一个实际的例子,上代码
使用OKHttp+Retrofit
//jar包支持
dependencies {
compile 'com.squareup.retrofit:retrofit:2.0.0-beta2'
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'
compile 'com.squareup.okhttp:okhttp:2.4.0'
}
创建我们所需要的JavaBean(数据对应的实体类)
public class User implements Serializable {
private String name;
private String pass;
//省略get set方法
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", pass='" + pass + '\'' +
'}';
}
}
创建我们所需要的请求接口
public interface UserService {
@GET("userAction/{name}") //url由方法中的传入参数动态的指定
Call<List<User>> getUser(@Path("name") String name);
}
//创建一个Retrofit实例 进行各种配置
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com")//地址前缀
.addConverterFactory(GsonConverterFactory.create()) //设置数据转换
.client(new OkHttpClient()) //设置客户端类型
.build();
//由Retrofit实例得到我们请求接口的实例
UserService userService = retrofit.create(UserService.class);
//同步或者异步的去获取数据
//这是异步获取获取 携带一个回调接口
call.enqueue(new Callback<List<User>>() {
@Override
public void onResponse(Response<List<User>> response, Retrofit retrofit) {
List<User> userList = response.body(); //这就是我们要的数据
}
@Override
public void onFailure(Throwable t) {
}
});
//这是同步获取参数 直接返回响应的信息
try {
Response<List<User>> response = call.execute();
List<User> users = response.body();
} catch (IOException e) {
e.printStackTrace();
}