作为目前Android最流行的Http Client框架之一,retrofit的学习已是大势所趋。
学习于:
http://www.jianshu.com/p/308f3c54abdd
http://blog.csdn.net/sk719887916/article/details/51755427
以下代码示例是retrofit的原始形态,分为两部分:
一是定义一个接口,其中@GET("api/public")
表示请求方式和请求的路径;@Query("uid") String uid
表示需要传入String类型的参数,对应的参数名是"uid"
;泛型代表着HTTP响应体转换的类型,此时是ResponseBody
。
public interface ApiService {
@GET("api/public")
Call<ResponseBody> getData(@Query("uid") String uid);
}
二是创建retrofit实例,baseUrl
表示请求的域名,同上述请求路径,参数组成完整的网址;然后创建上述接口的代理对象,调用异步方法,响应成功后走onResponse
,失败走onFailure
;
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
apiService = retrofit.create(ApiService.class);
apiService .enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
当然实际应用中要比上述中复杂的多,本系列将基于retrofit 2依次学习:注解,Converter,CallAdapter;
添加依赖:
compile 'com.squareup.retrofit2:retrofit:2.2.0'
注解
Retrofit 共22个注解,分为三类:HTTP请求方式,标记类,参数类;
HTTP请求方式:@GET,@POST
- 因为Retrofit 2.0使用了新的URL定义方式,BaseUrl与@POST 不是简单的组合在一起,所以BaseUrl根域名和@POST 中路径组合时应按照:
BaseUrl
: 以 / 结尾,@GET
或者@POST
: 不以 / 开头的标准,如图所示:
否则将出现的问题,如下图所示:
标记类:@FormUrlEncoded,@Multipart,@Streaming
@FormUrlEncoded
表明是一个表单格式的请求(Content-Type:application/x-www-form-urlencoded)-
@Multipart
表明是一个请求体支持文件上传的请求(Content-Type:multipart/form-data)- Content-Type只能是一种类型,不能同时使用上面两种注解。
@Streaming
下载大文件需要注入,防止下载过程中写入到内存中
参数类:@Field,@FieldMap,@Query,@QueryMap,@Url,@Path,@Part,@Body
- @Field,@FieldMap
用于@post
请求方式时传递简单的键值对,@Field
或@FieldMap
传递的参数时放在请求体的。额外需要添加@FormUrlEncoded
表示表单提交。
如果在@post
请求中使用@Field
和@FieldMap
时去掉@FromUrlEncoded
,那么程序会抛出java.lang.IllegalArgumentException: @Field parameters can only be used with form encoding. (parameter #1)
的错误异常。
如果将@FromUrlEncoded
添加在@GET
上面,同样的也会抛出
java.lang.IllegalArgumentException:FormUrlEncoded can only be specified on HTTP methods with request body (e.g., @POST).
的错误异常。
//一个参数
@FormUrlEncoded
@POST("API/public")
Call<ResponseBody> postData(@Field("uid") String uid);
//参数较多
@FormUrlEncoded
@POST("API/public")
Call<ResponseBody> postData(@FieldMap Map<String, String> params);
-
@Query,@QueryMap
用于@get
请求方式,传递简单的键值对,参数将直接拼接在url后面的
//只有一个参数且参数key值:uid
@GET("API/public")
Call<ResponseBody> getData(@Query("uid") String uid);
//参数较多
@GET("API/public")
Call<ResponseBody> getData(@QueryMap Map<String, String> params);
@Url
使用全路径复写baseUrl,适用于非统一baseUrl的场景,意思是当@GET
或@POST
注解的url为全路径时(如果和baseUrl不是一个路径),会直接使用@Url
注解中新的路径。@Path
用于替换和动态更新,如下所示使用@Path
时,id 所表示的路径中不能包含”/”,否则会将其转化为%2F。@Part
实现图片和参数上传,如果图片不确定@PartMap() Map<String, RequestBody> maps
代替@Part MultipartBody.Part file
@Multipart
@POST("API/public")
Call<ResponseBody> upload(@PartMap Map<String, String> params,//参数集合
@Part MultipartBody.Part file);//图片
// 封装 请求参数集合 map
...
// 封装 请求RequestBody
RequestBody requestFile =
RequestBody.create(MediaType.parse("multipart/form-data"), file);
MultipartBody.Part body =
MultipartBody.Part.createFormData("image", file.getName(), requestFile);
//
Call<ResponseBody> call = service.upload(maps,description,body);
...
-
@Body
也可以实现多张图片和参数的上传
//上传图片
@POST("API/public/ChangeUserImg")
Call<ResponseBody> upFile(@Body RequestBody Body);
MultipartBody.Builder builder = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("uid", mUid)
.addFormDataPart("pid", mPid);
for (int i = 0; i < mPathList.size(); i++) {
File file = new File(mPathList.get(i));
builder.addFormDataPart("file" + i, file.getName(), RequestBody.create(MediaType.parse("image/*"), file));
}
RequestBody body = builder.build();
Call<ResponseBody> call = service.upFile(body);
...
可以上传json数据
@POST("/uploadJson")
Call<ResponseBody> postJson(@Body RequestBody jsonBody);
RequestBody body=
RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"), jsonString);
Call<ResponseBody> call = APIService.postJson(requestBody);
...
Converter
默认情况下,Retrofit只能将HTTP请求体反序列化为OkHttp的ResponseBody类型,它只能接受它的RequestBody类型,
但是实际应用中会根据项目需求规定要转换的响应体类型,这时就需要添加转换器来支持其他类型,官方提供了六个序列化库,方便大家使用;
实际中Gson的序列化库是最常用的:
首先添加依赖:compile 'com.squareup.retrofit2:converter-gson:2.0.2'
通过GsonConverterFactory为Retrofit添加Gson支持:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
根据json结构生成实体bean类(ApiBeans),也就是请求的响应体类型
public interface ApiService {
@GET("api/public")
Call<ApiBeans> getData();
}
CallAdapter
retrofit
和rxjava
的结合使用就是同CallAdapter来实现的
首先导入依赖:
compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
通过RxJavaCallAdapterFactory为Retrofit添加RxJava 2支持:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
retrofit 可以提供多个CallAdapter,比如同时添加rxjava 1的支持,但也需要导入rxjava 1 的依赖和通过RxJavaCallAdapterFactory为Retrofit添加RxJava 1支持。
对于retrofit的学习才刚刚开始!
retrofit :入门
retrofit :Json数据缓存
retrofit :文件断点下载