Retrofit用法初识(一)

Retrofit用法初识(一)

Retrofit好。


1.导入依赖包

compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'

2.Retrofit具体用法

(1)创建业务请求接口
public interface BookService {
    @GET("book/search")
    Call<BookSearchResponse> getSearchBooks(@Query("name") String name, @Query("tag") String tag, @Query("start") int start, @Query("count") int count);
}
(2)创建一个Retrofit实例
Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.douban.com/v2/")
    .addConverterFactory(GsonConverterFactory.create())
    .build();

BookService service = retrofit.create(BookService.class);
(3)调用请求方法,得到Call实例
Call<BookSearchResponse> call = service.getSearchBooks("小王子", "", 0, 3);
(4)使用Call实例完成同异步请求
  • 同步请求:
BookSearchResponse response = call.execute().body();
  • 异步请求:
call.enqueue(new Callback<BookSearchResponse>() {
  @Override
  public void onResponse(Call<BookSearchResponse> call,         Response<BookSearchResponse> response) {
    asyncText.setText("异步请求结果:"
    +response.body().books.get(0).altTitle);
  }
  @Override
  public void onFailure(Call<BookSearchResponse> call, Throwable t) {

  }
});

3.Retrofit其他方法

(1)Url配置
@GET("book/{id}")
Call<BookSearchResponse> getBook(@Path("id") String id);

Call<BookSearchResponse> call = service.getBook("1003078");

此时的url地址为:

https://api.douban.com/v2/book/1003078

(2)Get方法

@Query后的参数为单个,@QueryMap后的参数可以一个Map集合:

public interface BookService {
    @GET("book/search")
    Call<BookSearchResponse> getSearchBooks(@QueryMap Map<String, String> options);
}

另若是Map中相同Key值,不同的value值,可以将所有的value放置在列表中,然后在同一个@Query下完成添加:

public interface BookService {
    @GET("book/search")
    Call<BookSearchResponse> getSearchBooks(@Query("q") List<String> name);
}

最后@Query的值可以为null。

(3)Post方法

Post请求需要把请求参数放置在请求体中,而非拼接在url后面,先来看一个简单的例子:

@FormUrlEncoded
@POST("book/reviews")
Call<String> addReviews(@Field("book") String bookId,
@Field("title") String title,@Field("content") String content, @Field("rating") String rating);
  • @FromURLEncoded

@FormUrlEncoded将会自动将请求参数的类型调整为application/x-www-form-urlencoded,假如content传递的参数为Good Luck,那么最后得到的请求体就是:

content=Good+Luck
  • @Field和@FieldMap

    类似@Query与@QueryMap,
    @Field注解将每一个请求参数都存放至请求体中,还可以添加encoded参数,该参数为boolean型,具体的用法为

@Field(value = "book", encoded = true) String book

encoded参数为true的话,key-value-pair将会被编码,即将中文和特殊字符进行编码转换。
而Post如果有更多的请求参数,这个时候就可以用@FieldMap:

@FormUrlEncoded
@POST("book/reviews")
Call<String> addReviews(@FieldMap Map<String, String> fields);
  • @Body

如果Post请求参数有多个,那么统一封装到类中应该会更好,这样维护起来会非常方便

@FormUrlEncoded
@POST("book/reviews")
Call<String> addReviews(@Body Reviews reviews);

public class Reviews {
    public String book;
    public String title;
    public String content;
    public String rating;
}
(4)上传
  1. 首先还是需要新建一个interface用于定义上传方法:
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);
}
  1. 接下来我们还需要在Activity和Fragment中实现两个工具方法:
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);
}
  1. 接下来就是最终的上传文件代码:
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());
    }
});
(5)其他方法

除了Get和Post请求,Http请求还包括Put,Delete等等,用法和Post相似,所以就不再单独介绍了。

4.其他注意事项

  • 添加自定义的header

我们知道http是有请求头的,有些时候我们是需要填写或者配置一下请求头的,比如说,文件上传,或者cookie保持。这里的请求头支持动态配置和静态配置。

  • 静态方法
public interface BookService {
    @Headers({
        "Accept: application/vnd.yourapi.v1.full+json",
        "User-Agent: Your-App-Name"
    })
    @GET("book/search")
    Call<BookSearchResponse> getSearchBooks(@Query("q") String name, 
            @Query("tag") String tag, @Query("start") int start, 
            @Query("count") int count);
}
  • 动态方法
public interface BookService {
    @GET("book/search")
    Call<BookSearchResponse> getSearchBooks(
    @Header("Content-Range") String contentRange, 
    @Query("q") String name, @Query("tag") String tag, 
    @Query("start") int start, @Query("count") int count);
}

5.结尾

你做的还不够好。

咳咳,本文大面积整理(抄袭)介篇

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值