Retrofit是一个类型安全的HTTP的客户端,在Android和Java中都可使用。Retrofit通过注解实现RESTful网络接口,底层使用Okhttp完成网络请求的实现。另外,Retrofit封装了主线程和子线程的切换以及网络数据的解析,在使用上要比OkHttp便利不少。
Retrofit的使用步骤
- 添加依赖
dependencies {
//Retrofit依赖
compile 'com.squareup.retrofit2:retrofit:2.3.0'
//Gson转换器,将网络响应使用Gson转换成Java Bean
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
}
注意:如果使用了ProGuard,还需要在proguard-rules.pro文件中配置:
#平台对Android上不存在的类型调用Class.forName来确定平台。
-dontnote retrofit2.Platform
#在iOS上的RoboVM上运行时使用的平台。将不会在运行时使用。
-dontnote retrofit2.Platform$IOS$MainThreadExecutor
#在Java 8虚拟机上运行时使用的平台。将不会在运行时使用。
-dontwarn retrofit2.Platform$Java8
#保留泛型类型信息,以供转换器和适配器的反射使用。
-keepattributes Signature
#保留声明的已检查异常以供代理实例使用。
-keepattributes Exceptions
-dontwarn okio.**
-dontwarn javax.annotation.**
# Gson
-keep class com.example.testing.retrofitdemo.bean.**{
*;} # 自定义数据模型的bean目录
- 定义网络服务接口
创建一个接口,专门负责定义网络API。比如我们定义接口GitHubService用于调试GitHub开放的API,一个API对应一个方法。
public interface GitHubService {
//配置GET请求和URL路径
@GET("users/{user}/repos")
//返回为Call<T>对象,泛型T表示网络解析后结果的类型
//@Path("user")注解表示参数user会替换URL路径中的{user}
Call<List<Repo>> listRepos(@Path("user") String user);//返回值必须声明成Retrofit中内置的Call类型,并通过泛型来指定服务器响应的数据应该装换成什么对象。
}
- 生成对应的Java Bean类
Github的网络API获取到的网络结果是JSON字符串,因此我们可以生成对应的Java Bean类,如下图。
- 实现网络服务接口
我们使用Builder模式创建一个Retrofit对象,并且配置API的基地址:
//在oncreate方法中创建Retrofit对象
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addConverterFactory(GsonConverterFactory.create())//配置Gson转换器
.build();
//使用Retrofit对象返回一个GitHubService的实现
GitHubService gitHubService = retrofit.create(GitHubService.class);
- 发送网络请求
在AndroidManifest.xml中添加网络权限:
<uses-permission android:name="android.permission.INTERNET"/>
接着使用githubService调用接口方法获取一个Call对象,然后使用该对象enqueue方法异步发送网络请求:
//在oncreate方法中添加下述代码
Call<List<Repo>> octocat = gitHubService.listRepos("octocat");
octocat.enqueue(mCallback);
//Retrofit会自动根据注解中配置的服务器接口地址去进行网络请求,服务器响应的数据会回调到enqueue方法中传入的Callback实现里面。需要注意的是,当发起请求的时候,retrofit会自动在内部开启子线程,当数据回调到Callback中之后会自动切换回主线程,整个操作过程不用考虑线程切换问题。
private Callback<List<Repo>> mCallback = new Callback<List<Repo>>() {
@Override
public void onResponse(Call<List<Repo>> call, Response<List<Repo>> response) {
List<Repo> body = response.body();
for (int i = 0; i < body.size(); i++) {
Repo repo = body.get(i);
Log.d(TAG, "onResponse: " + repo.getName());
}
}
@Override
public void onFailure(Call<List<Repo>> call, Throwable t) {
Log.d(TAG, "onFailure: " + t.getLocalizedMessage());
}
};
- 运行结果