一.概述
Retrofit是Square公司开发的一款针对Android网络请求的框架,底层基于OkHttp3实现的。Retrofit用注解来描述一个HTTP请求,
将一个HTTP请求抽象成一个Java接口,然后用了Java动态代理的方式,动态的将这个接口的注解“翻译”成一个HTTP请求,最后通过OkHttp3发送这个HTTP请求。导包:
*这里需要值得注意的是导入的retrofit2包的版本必须要一致,否则就会报错。compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'//Retrofit2所需要的包 compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'//ConverterFactory的Gson依赖包 compile 'com.squareup.retrofit2:converter-scalars:2.0.0-beta4'//ConverterFactory的String依赖包
二.Retrofit的基本使用
(1)get请求
@Query首先需要定义一个接口对象
public interface RequestServes {
@GET("top250")
Call<HttpResult<List<Subject>>> getTopMovie(@Query("start") int start, @Query("count") int count);
}
*@GET注解就表示get请求,@Query表示请求参数,将会以key=value的方式拼接在url后面。拼接出来的url地址:https://api.douban.com/v2/movie/top250?start=0&count=10
然后创建一个Retrofit的实例,完成相应的请求
Retrofit retrofit=new Retrofit.Builder()
.baseUrl("https://api.douban.com/v2/movie/")
.addConverterFactory(GsonConverterFactory.create())
.build();
RequestServes requestServes=retrofit.create(RequestServes.class);
Call<HttpResult<List<Subject>>> httpResultCall=requestServes.getTopMovie(0,10);
httpResultCall.enqueue(new Callback<HttpResult<List<Subject>>>() {
@Override
public void onResponse(Call<HttpResult<List<Subject>>> call, Response<HttpResult<List<Subject>>> response) {
List<Subject> subjects=response.body().getSubjects();
}
@Override
public void onFailure(Call<HttpResult<List<Subject>>> call, Throwable t) {
}
});
*
baseUrl就是网络请求URL的基地址,一般为域名或IP地址、端口号等。.addConverterFactory是用于对象转化的,GsonConverterFactory.create()表示调用Gson库来解析json返回值。
*httpResultCall.enqueue是异步的访问数据,同步的访问方式为httpResultCall.execute。
@PATH:
定义一个借口对象
public interface RequestServes { @GET("{top}") Call<HttpResult<List<Subject>>> getTopMovie(@Path("top") String top); }
*我们的@GET注解中使用{top}声明了访问路径,这里你可以把{top}当做占位符,而实际运行中会通过@PATH("top")所标注的参数进行替换。拼接出来的url地址:https://api.douban.com/v2/movie/top250
请求时代吗://...省略 Call<HttpResult<List<Subject>>> httpResultCall=requestServes.getTopMovie("top250"); //...省略
(2)Post请求
@FormUrlEncoded以表单的形式传递键值对。
比如登录时:
*通过@POST指明url,添加FormUrlEncoded,然后通过@Field将每一个请求参数都存放至请求体中。public interface RequestServes { @POST("login") @FormUrlEncoded Call<User> login(@Field("username") String username, @Field("password") String password); }
请求时代码:
@Multipart//...省略 Call<HttpResult<List<Subject>>> httpResultCall=requestServes.getTopMovie("test","123123"); //...省略
文件上传
首先还是创建一个接口对象
然后,在Activity中实现两个工具方法:public interface FileUploadService { // 上传单个文件 @Multipart @POST("upload") Call<ResponseBody> uploadFile( @Part("description") RequestBody description, @Part MultipartBody.Part file); // 上传多个文件 @Multipart @POST("upload") Call<ResponseBody> uploadMultipleFiles( @Part("description") RequestBody description, @Part MultipartBody.Part file1, @Part MultipartBody.Part file2); }
public static final String MULTIPART_FORM_DATA = "multipart/form-data"; @NonNull private RequestBody createPartFromString(String descriptionString) { return RequestBody.create( MediaType.parse(MULTIPART_FORM_DATA), descriptionString); } @NonNull private MultipartBody.Part prepareFilePart(String partName, Uri fileUri) { File file = FileUtils.getFile(this, fileUri); // 为file建立RequestBody实例 RequestBody requestFile = RequestBody.create(MediaType.parse(MULTIPART_FORM_DATA), file); // MultipartBody.Part借助文件名完成最终的上传 return MultipartBody.Part.createFormData(partName, file.getName(), requestFile); }
最后,实现上传文件代码
Uri file1Uri = ... // 从文件选择器或者摄像头中获取 Uri file2Uri = ... // 创建上传的service实例 FileUploadService service = ServiceGenerator.createService(FileUploadService.class); // 创建文件的part (photo, video, ...) MultipartBody.Part body1 = prepareFilePart("video", file1Uri); MultipartBody.Part body2 = prepareFilePart("thumbnail", file2Uri); // 添加其他的part RequestBody description = createPartFromString("hello, this is description speaking"); // 最后执行异步请求操作 Call<ResponseBody> call = service.uploadMultipleFiles(description, body1, body2); call.enqueue(new Callback<ResponseBody>() { @Override public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { Log.v("Upload", "success"); } @Override public void onFailure(Call<ResponseBody> call, Throwable t) { Log.e("Upload error:", t.getMessage()); } });