Retrofit是Square公司开发的一款针对Android网络请求的框架,Retrofit2底层基于OkHttp实现的
GitHub源码地址:https://github.com/square/retrofit
1、使用Retrofit需要添加一下依赖:
compile 'com.squareup.retrofit2:retrofit:2.1.0'
2、使用Retrofit进行网络请求的方式:
2.1 Get请求()
2.1.1 创建业务请求接口
2.1.2 创建Retrofit实例,并完成相应的配置
2.1.3 调用请求方法,并得到Call实例
2.1.4 使用Call实例完成同步或异步请求
同步请求:call.execute();
异步请求:call.enqueue();
2.2 Post请求
2.2.1 创建业务请求接口
2.2.2 创建Retrofit实例,并完成相应的配置
2.2.3 调用请求方法,并得到Call实例
2.2.4 使用Call实例完成同步或异步请求
同步请求:call.execute();
异步请求:call.enqueue();
3.Retrofit的链式编程
---------------------------------------------------------------------------------------------------------------------------------------
2.1 Get请求:
2.1.1 创建业务请求接口
public interface HttpApi {
/** * * @GET("book/search") -----> book/search :(完整url= baseUrl + book/search) * BookSearchResponse ----->BookSearchResponse创建方式:1、在接口文档中获得json或者在浏览器中获得接口返回的json(仅限GET请求)---> 2、在工程中创建BookSearchResponse.class---> * 3、在BookSearchResponse中点击右键---> 4、点击Generate... ---> 5、点击GsonFormat --->6、将步骤 1 中获得的json粘贴进GsonFormat框,并一路点击ok到结束 * @Query("q") -----> q :为接口中的请求参数 如果请求参数为非必填,即使不传该参数,服务端也可以正常解析 * */ @GET("book/search") public abstract Call<BookSearchResponse> getSearchBooks( @Query("q") String name, @Query("tag") String tag, @Query("start") int start, @Query("count") int count); }
或者
public interface HttpApi {
/** * @GET("book/search") -----> book/search :(完整url= baseUrl + book/search) * BookSearchResponse ----->BookSearchResponse创建方式:1、在接口文档中获得json或者在浏览器中获得接口返回的json(仅限GET请求)---> 2、在工程中创建BookSearchResponse.class---> * 3、在BookSearchResponse中点击右键---> 4、点击Generate... ---> 5、点击GsonFormat --->6、将步骤 1 中获得的json粘贴进GsonFormat框,并一路点击ok到结束 * @QueryMap Map<String, String> options ----->options:为存放请求参数的集合
*/ @GET("book/search") public abstract Call<BookSearchResponse> getSearchBooks(@QueryMap Map<String, String> options);
}
2.1.2 创建Retrofit实例,并完成相应的配置
//实例化Retrofit,用来实例化HttpApi
Retrofit retrofit = new Retrofit .Builder() .baseUrl(url) .addConverterFactory(GsonConverterFactory.create()) .build(); //使用Retrofit实例化接口 HttpApi httpApi = retrofit.create(HttpApi.class);
2.1.3 调用请求方法,并得到Call实例
对应于 2.1.1 中的 @Query 注解: Call<BookSearchResponse> call = httpApi.getSearchBooks("小王子", "", 0, 3);
等价于 Call<BookSearchResponse> call = httpApi.getSearchBooks("小王子", null, 0, 3);
对应于 2.1.1 中的 @QueryMap 注解: Map<String, String> map = new HashMap<>(); map.put("q", "小王子"); map.put("tag", null); map.put("start", "0"); map.put("count", "3"); Call<BookSearchResponse> call = httpApi.getSearchBooks(map);
2.1.4 使用Call实例完成同步或异步请求
//在主线中只能异步调用 call.enqueue(new Callback<CollectResponse>() { @Override public void onResponse(Call<CollectResponse> call, Response<CollectResponse> response) { if (response.isSuccessful()) {
Toast.makeText(CollectActivity.this, "请求网络成功!", Toast.LENGTH_SHORT).show();
} else { Toast.makeText(CollectActivity.this, "请求网络失败!", Toast.LENGTH_SHORT).show(); } } @Override public void onFailure(Call<CollectResponse> call, Throwable t) { Toast.makeText(CollectActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show(); } });
---------------------------------------------------------------------------------------------------------------------------------------
2.2 Post请求
2.2.1 创建业务请求接口
public interface HttpApi {
/** * @FormUrlEncoded ----->FormUrlEncoded 将会自动将请求参数的类型调整为application/x-www-form-urlencoded,假如content传递的参数为Good Luck,那么最后得到的请求体就是content=Good+Luck, FormUrlEncoded不能用于Get请求
* @POST("login") -----> login :(完整url= baseUrl + login) * LoginResponse ----->LoginResponse创建方式:1、在接口文档中获得json或者在浏览器中获得接口返回的json(仅限GET请求)---> 2、在工程中创建LoginResponse.class---> * 3、LoginResponse中点击右键---> 4、点击Generate... ---> 5、点击GsonFormat --->6、将步骤 1 中获得的json粘贴进GsonFormat框,并一路点击ok到结束 * @Field("username") ----->username:为请求参数
*/
@FormUrlEncoded @POST("login") public abstract Call<LoginResponse> login(@Field("username") String username,@Field("password") String password);
}
或者
public interface HttpApi {
/** * @FormUrlEncoded ----->FormUrlEncoded 将会自动将请求参数的类型调整为application/x-www-form-urlencoded,假如content传递的参数为Good Luck,那么最后得到的请求体就是content=Good+Luck, FormUrlEncoded不能用于Get请求
* @POST("login") -----> login :(完整url= baseUrl + login) * LoginResponse ----->LoginResponse创建方式:1、在接口文档中获得json或者在浏览器中获得接口返回的json(仅限GET请求)---> 2、在工程中创建LoginResponse.class---> * 3、LoginResponse中点击右键---> 4、点击Generate... ---> 5、点击GsonFormat --->6、将步骤 1 中获得的json粘贴进GsonFormat框,并一路点击ok到结束 * @FieldMap Map<String,String> paramMap ----->paramMap:为存放请求参数的集合
*/
@FormUrlEncoded @POST("login") public abstract Call<LoginResponse> login(@FieldMap Map<String, String> paramMap);
}
2.2.2 创建Retrofit实例,并完成相应的配置
HttpApi httpApi = new Retrofit
.Builder()
.baseUrl(Constant.URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(HttpApi.class);
2.2.3 调用请求方法,并得到Call实例
对应于 2.2.1 中的 @Field 注解:
Call<LoginResponse> call = service.login("viciy","123");
对应于 2.2.1 中的 @FieldMap 注解:
HashMap localHashMap = new HashMap();
localHashMap.put("username", "viciy");
localhashMap.put("password", "123");
Call<LoginResponse> call = httpApi.login(localHashMap);
2.2.4 使用Call实例完成同步或异步请求
//在主线中只能异步调用
call.enqueue(new Callback<LoginResponse>() {
@Override
public void onResponse(Call<CollectResponse> call, Response<LoginResponse> response) {
if (response.isSuccessful()) Toast.makeText(LoginActivity.this, "登录成功!", Toast.LENGTH_SHORT).show(); } else {//判断登陆错误类型 Toast.makeText(LoginActivity.this, loginResponse.error.getMsg(), Toast.LENGTH_SHORT).show(); } } @Override
public void onFailure(Call<CollectResponse> call, Throwable t) {
Toast.makeText(LoginActivity.this, "网络繁忙,请重试!", Toast.LENGTH_SHORT).show(); } });
---------------------------------------------------------------------------------------------------------------------------------------
3.Retrofit的链式编程:
以登录接口为例:
new Retrofit
.Builder() .baseUrl(url) .addConverterFactory(GsonConverterFactory.create()) .build() .create(HttpApi.class) //业务请求接口的.class文件 .login(map) //login(map)为HttpApi接口中自定义的请求方法 .enqueue(new Callback<LoginResponse>() { //LoginResponse 参见2.1.1或2.2.1的注释 @Override
public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
if (response.isSuccessful()) { Toast.makeText(LoginActivity.this, "登录成功!", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(LoginActivity.this, loginResponse.error.getMsg(), Toast.LENGTH_SHORT).show(); } }
@Override
public void onFailure(Call<LoginResponse> call, Throwable t) {
Toast.makeText(LoginActivity.this, "网络繁忙,请重试!", Toast.LENGTH_SHORT).show(); }
});