介绍
Retrofit的英文意思是改进。是一个网络请求框架,底层本质走的是OkHttp。Retrofit实质是对OkHttp进行了封装,将Http请求抽象成Java的接口。
定义Http请求
Retrofit将每一个Http请求抽象成Java接口中的方法。用注解配置网络请求的参数。例如:
public interface MusicService {
@GET("/searchMusic")
Call queryMusicByName(@QueryMap Map options);
}
定义了一个MusicService
接口中的queryMusicByName
代表了一个网络请求。方法上面的@GET("/searchMusic")
注解描述了该网络请求是GET
方法,网络请求的path是/searchMusic
。至此就定义好了一个http的网络请求。
创建Retrofit实例
一个http请求定义好之后,那就要思考这个http请求要用什么来发送出去。那就了解一下怎么创建Retrofit实例。
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://api.apiopen.top")
.addConverterFactory(GsonConverterFactory.create())
.build();
retrofit采取builder模式进行构造,上面的例子分别通过Builder设置host、添加数据转化器。
发送网络请求
知道了怎么创建一个retrofit实例,有了发送网络请求的工具。那接下来就是需要了解一下怎么把一个网络请求发送出去了。
先是创建接口的实例
MusicService musicService = retrofit.create(MusicService.class);
接着是通过接口实例调用定义的Http请求方法获取Call对象。
Call call = musicService.queryMusicByName(params);
最后是通过call方法执行同步或者异步请求将http请求发送出去
- 同步请求
//不能再主线程中执行同步请求
try {
call.execute();
} catch (IOException e) {
e.printStackTrace();
}
- 异步请求
call.enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
//回调已经是主线程 可以执行UI操作
}
@Override
public void onFailure(Call call, Throwable t) {
//回调已经是主线程 可以执行UI操作
}
});
注意:同步请求不能在Android主线程中发起。异步请求的CallBack回调相比于OkHttp,Retrofit已经做了线程的切换处理,回调方法已经是主线程可以执行相应的UI操作。
OkHttp的简单使用
既然retrofit是在OkHttp之上做了一层封装,那简单看一下相比于OkHttp,Retrofit有什么不同。先看一下OkHttp的简单用法。
- OKHttp的异步请求
OkHttpClient httpClient = new OkHttpClient.Builder().build();
Request request = new Request.Builder()
.url("http://api.apiopen.top")
.build();
httpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
//回调是子线程,不能做UI操作
}
@Override
public void onResponse(Call call, final Response response) throws IOException {
//回调是子线程,不能做UI操作
}
});
使用OkHttp发起一个请求首先是创建一个OkHttpClient
实例,接着构造一个Request
请求,再通过OkHttpClient
实例调用newCall(Request)
方法得到一个Call
实例。最后就跟Retrofit
一样了,通过调用enqueue()
方法发起网络请求。不过跟Retrofit
不同的是,回调的onResponse
和onFailure
是执行在子线程的。
- OkHttp的同步请求
try {
Response response = httpClient.newCall(request).execute();
} catch (IOException e) {
e.printStackTrace();
}
同样的同步请求不能在主线程发起,否则会crash。