retrofit作为现在最火的框架之一,学习学习还是很有必要的。接下来我就来说说retrofit的一些基本用法。
retrofit2.0它依赖于OkHttp,而且这部分也不再支持替换。在这里我们也不需要显示的导入okHttp,在retrofit中已经导入okhttp3。
使用retrofit的步骤:
1、添加最新的官方依赖:retrofit
compile 'com.squareup.retrofit2:retrofit:2.1.0'
2、使用java接口构建Http请求的API;
3、通过Build模式构建Retrofit对象,可以在Build中对Retrofit进行必要的配置
4、调用API接口进行网络请求。
接下来就从第二部开始,进行一下最基本的Http请求
第一步:构建Http请求的API
创建一个API接口
public interface GitHubApi {
@GET("repos/{owner}/{repo}/contributors")
Call<ResponseBody>contributorsBySimpleGetCall(@Path("owner") String owner, @Path("repo") String repo);
}
构建Retrofit对象
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
调用API进行网络请求
GitHubApi repo = retrofit.create(GitHubApi.class);
Call<List<TestBean>> call = repo.contributorsByAddConverterGetCall(mUserName, mRepo);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
tv.setText(response.body().string());
Log.d("数据",response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.d("异常", t.toString());
}
});
通过
GitHubApi repo = retrofit.create(GitHubApi.class);
最终构建的网址是:https://api.github.com/repos/square/retrofit/contributors
通过这几部就可以进行基本的网络请求了
下面说说对Retrofit的配置:
Retrofit通过addConverterFactory指定一个factory来对响应反序列化
从新配置API:
@GET("repos/{owner}/{repo}/contributors")
Call<List<TestBean>> contributorsByAddConverterGetCall(@Path("owner") String owner, @Path("repo") String repo)
构建Retrofit ,并配置:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
//指定factory
.addConverterFactory(GsonConverterFactory.create())
.build();
在这里我们需要为retrofit添加gson转换器的依赖。添加过converter-gson后不用再添加gson库。在converter-gson中已经包含gson。
compile 'com.squareup.retrofit2:converter-gson:2.0.1'
请求:
GitHubApi repo = retrofit.create(GitHubApi.class);
Call<List<TestBean>> call = repo.contributorsByAddConverterGetCall(mUserName, mRepo);
call.enqueue(new Callback<List<TestBean>>() {
@Override
public void onResponse(Call<List<TestBean>> call, Response<List<TestBean>> response) {
List<TestBean> contributorList = response.body();
for (TestBean contributor : contributorList) {
Log.d("contributions", "成功了");
Log.d("login", contributor.getLogin());
Log.d("contributions", contributor.getContributions() + "");
}
tv.setText(contributorList.toString());
}
@Override
public void onFailure(Call<List<TestBean>> call, Throwable t) {
Log.d("contributions", "失败了");
}
});
retrofit还支持其他许多json解析库:
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
retrofit2.0依赖OkHttp,他也允许我们对OkHttp进行配置:
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(httpLoggingInterceptor)
.build();
Retrofit retrofit = new Retrofit.Builder().addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.client(okHttpClient)
.baseUrl("https://api.github.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
这里需要添加依赖:
compile 'com.squareup.okhttp3:logging-interceptor:3.1.2'
以上说的都是异步请求;再来说说同步请求:
这里我们可以直接通过call.execute()执行一个同步请求,由于不允许在主线程中进行网络请求操作,所以我们需要再子线程中进行执行。
GitHubApi repo = retrofit.create(GitHubApi.class);
final Call<List<TestBean>> call = repo.contributorsByAddConverterGetCall(mUserName, mRepo);
new Thread(new Runnable() {
@Override
public void run() {
try{
Response<List<TestBean>> response = call.execute();
List<TestBean> contributorsList = response.body();
for (TestBean contributor : contributorsList){
Log.d("login",contributor.getLogin());
Log.d("contributions",contributor.getContributions()+"");
//子线程不能更新UI
// tv.setText(contributor.toString());
}
}catch (IOException e){
e.printStackTrace();
}
}
}).start();
注意:无论是同步操作还是异步操作每一个call对象实例只能被执行一次。否则将会出现异常,当然我们可以通过Clone方法创建一个一模一样的实例,
final Call<List<TestBean>> cloneCall = call.clone();
当然了在进行网络请求时我们也可以终止一个请求通过:
call.cancel();
大家 应该已经看出来了以上都是不带参数的get请求,那带参数的get请求与post请求应该怎么做呢?
其实我们还是以构建API的形式来解决这个问题的:
//带参数的get请求
@GET("search/repositories")
Call<RetrofitBean> queryRetrofitByGetCall( @Query("参数1")String value,
@Query("参数2")int value,
@Query("参数3")int value);
//get通过map传递参数
@GET("search/repositories")
Call<RetrofitBean> queryRetrofitByGetCallMap(@QueryMap Map<String,String> map);
//post请求
@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);
//post通过map传递参数
@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@FieldMap Map<String,String> fieldMap);