android Retrofit2.0 RxJava2.0

本文介绍Retrofit 2.0的基本用法,包括依赖添加、接口声明、OkHttpClient与Retrofit对象创建及缓存策略设置等内容。Retrofit是一个类型安全的REST客户端请求库,用于Android和Java平台。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

android Retrofit2.0

Retrofit
一个用于Android和Java平台的类型安全的网络框架(是一套注解形式的网络请求封装库,REST API协议),Retrofit是一个Square开发的类型安全的REST安卓客户端请求库,
为网络认证、API请求以及用OkHttp发送网络请求提供了强大的框架 。
Retrofit 把REST API返回的数据转化为Java对象,就像ORM框架那样,把数据库内的存储的数据转化为相应的Java bean对象。

REST(Resources Representational State Transfer–资源表现层状态转化)是一组架构约束条件和原则。
RESTful架构都满足以下规则:
1、每一个URI代表一种资源;
2、客户端和服务器之间,传递这种资源的某种表现层(“资源”具体呈现出来的形式,比如.txt,.png,.jpg) ;
3、客户端通过四个HTTP动词(GET用来获取资源,POST用来新建或更新资源,PUT用来更新资源,DELETE用来删除资源),对服务器端资源进行操作,实现”表现层状态转化”。

Retrofit基本用法
1、build.gradle中添加依赖

compile 'com.squareup.okhttp3:okhttp:3.4.1'
compile 'com.squareup.okhttp3:logging-interceptor:3.4.1'
compile 'com.google.code.gson:gson:2.5'
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
compile 'com.squareup.retrofit2:adapter-rxjava2:2.1.0'
compile 'io.reactivex.rxjava2:rxjava:2.0.1'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'

2、创建接口、声明API

public interface GitAPI {
    //请求url:baseURL/users/{user} 下载、返回的响应体为User
    @Headers("Cache-Control: max-age=64")    //设置单个请求的缓存时间
    @GET("users/{user}") 
    Call<User> userInfo(@Path("user") String user);    

    //上传图片
    @Multipart
    @POST("uploadaddr") // 根据实际填入
    Observable<String> uploadUserFile(@Part("fileName") RequestBody description, @Part("file\"; filename=\"image.png\"")RequestBody img);  
}

3、创建OkHttpClient、Retrofit对象,执行异步调用

File cacheDirectory = new File(getApplicationContext().getCacheDir().getAbsolutePath(), "Cache"); 
Cache cache = new Cache(cacheDirectory, 10 * 1024 * 1024)); // 创建缓存类

private Interceptor cacheInterceptor() {
   return new Interceptor() {  //okHttp的Interceptors 可对所有请求进行拦截
       @Override
       public Response intercept(Chain chain) throws IOException {
            String username = "UserName";
            String password = "Password";
            String credentials = username + ":" + password;
            String basic = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);

            Request request = chain.request();
            if (!AppUtil.isNetworkReachable(sContext)) { // 网络不可达,强制使用缓存
                request = request.newBuilder()
                          .cacheControl(CacheControl.FORCE_CACHE)  //设置缓存控制为"强制缓存"
                          .build();
            }

            //添加请求验证信息头部
            Request.Builder requestBuilder = request.newBuilder()    //Basic Authentication,也可用于token验证,OAuth验证
              .header("Authorization", basic)
              .header("Accept", "application/json")
              .method(request.method(), request.body());

            Request request0 = requestBuilder.build();

            Response response = chain.proceed(request0);
            if (AppUtil.isNetworkReachable(sContext)) {
                String cacheControl = request0.cacheControl().toString(); //获取Request缓存设置
                if (TextUtils.isEmpty(cacheControl)) {
                    cacheControl = "public, max-age=60"; // 拦截request,添加缓存设置
                }
                return response.newBuilder()
                            .header("Cache-Control", cacheControl) //根据@Headers里的配置,对Response缓存进行设置
                            .removeHeader("Pragma")
                            .build();
            } else {
                int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale
                return response.newBuilder()
                            .header("Cache-Control", "public, only-if-cached, max-stale="+maxStale)
                            .removeHeader("Pragma")
                            .build();
            }

       }
   };
}

OkHttpClient client = new OkHttpClient(); //1、初始化OkHttpClient
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
client = new OkHttpClient.Builder()
      .addInterceptor(cacheInterceptor())  //通过Header和Interceptor配置实现缓存策略, okHttp的拦截器Interceptors可对所有请求进行再处理
      .retryOnConnectionFailure(true)
      .connectTimeout(15, TimeUnit.SECONDS)
      .cache(cache) // 设置缓存,okhttp默认是没有缓存,且没有缓存目录的
      .cookieJar(new CookieJar() { //Cookies由CookieJar统一管理,对CookieJar进行设置就可以达到Cookies缓存
         private final HashMap<String, List<Cookie>> cookieStore = new HashMap<>();
         @Override
         public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
            cookieStore.put(url.host(), cookies);
         }
         @Override
         public List<Cookie> loadForRequest(HttpUrl url) {
            List<Cookie> cookies = cookieStore.get(url.host());
            return cookies != null ? cookies : new ArrayList<Cookie>();
         }
       }).build();

Retrofit retrofit = new Retrofit.Builder() //2、创建Retrofit 
      .client(client) //设置OKHttpClient   
      .baseUrl("https://api.github.com/")  //设置baseUrl,注意,baseUrl必须后缀"/",Retrofit在创建时候传入了BaseUrl,基本上所有请求都基于该BaseUrl了。
                                             //但是总有些API不是以该BaseUrl开头的(可能不是restful API的),Retrofit提供了注解@Url,可直接对Url进行访问
      .addConverterFactory(GsonConverterFactory.create())  //添加Gson转换器
      .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // RxJava2.0
      .build();

GitAPI gitAPI = retrofit.create(GitAPI.class); //3、获取GitHub的API

//Call方式调用
Call<user> call = gitAPI.userInfo("yourname"); //4、异步调用,最终的请求url:https://api.github.com/users/yourname
call.enqueue(new Callback<User>() {
      @Override 
      public void onResponse(Call<user> call, Response<User> response) {
         User body = response.body();
         Log.d("onResponse", "body = "+body.toString());
      } 
      @Override 
      public void onFailure(Call<user> call, Throwable t) {
      }
});

//Observable方式调用(调用RxJava Observable类) 
String des = "upload a image!";
RequestBody description = RequestBody.create(MediaType.parse("multipart/form-data"), des);
File file = new File(imgpath); // 图像文件
RequestBody imgbody = RequestBody.create(MediaType.parse("multipart/form-data"),file);

Observable<String> observable = gitAPI.uploadUserFile(description, imgbody);  
observable.subscribeOn(Schedulers.io())
      .unsubscribeOn(Schedulers.io())
      .observeOn(AndroidSchedulers.mainThread());
      .subscribe(new Subscriber<String>() {
          @Override
          public void onCompleted() {}
          @Override
          public void onError(Throwable e) {}
          @Override
          public void onNext(String s) {}
      });   

public class User {
      private String login;
      private String id;
      private String avatar_url;
      ...
      private String created_at;
      private String updated_at;
}

//Retrofit加入缓存策略,设置缓存就需要用到OkHttp的interceptors,缓存的设置需要靠请求和响应头
OkHttp3中Cache类是用来定义缓存的,几种缓存策略:
noCache :不使用缓存,全部走网络
noStore : 不使用缓存,也不存储缓存
onlyIfCached : 只使用缓存
maxAge :设置最大失效时间,失效则不使用
maxStale :设置最大失效时间,失效则不使用
minFresh :设置最小有效时间,失效则不使用
FORCE_NETWORK : 强制走网络
FORCE_CACHE :强制走缓存

Retrofit注解:Retrofit使用注解来声明API的请求方式、请求参数等
retrofit注解:
方法注解,包含@GET、@POST、@PUT、@DELETE、@PATH、@HEAD、@OPTIONS、@HTTP。
标记注解,包含@FormUrlEncoded、@Multipart、@Streaming。
参数注解,包含@Query,@QueryMap、@Body、@Field,@FieldMap、@Part,@PartMap。
其他注解,@Path、@Header,@Headers、@Url

1、@GET GET网络请求方式
2、@POST POST网络请求方式
3、@Headers() 头信息参数
4、@Path() 路径参数,替换url地址中 { } 所括的部分
5、@Query() 查询参数,将在url地址中追加类似“page=1”的字符串,形成提交给服务端的请求参数
6、@QueryMap 查询参数集合,将在url地址中追加类似 “type=text&username=abc&password=123”的字符串
7、@FormUrlEncoded 对表单域中填写的内容进行编码处理,避免乱码
8、@Field() 指定form表单域中每个空间的额name以及相应的数值
9、@FieldMap 表单域集合
10、@Multipart Post提交分块请求,如果上传文件,必须指定Multipart
11、@Body Post提交分块请求

@HTTP:可以替代其他方法的任意一种    
@HTTP(method = "get", path = "users/{user}", hasBody = false) //// method 表示请的方法,不区分大小写, path表示路径, hasBody表示是否有请求体
Call<ResponseBody> getUser(@Path("user") String user);

@Url:使用全路径复写baseUrl,适用于非统一baseUrl的场景。
@GET
Call<ResponseBody> getUser(@Url String url);

@Streaming:用于下载大文件
@Streaming
@GET
Call<ResponseBody> downloadFileWithDynamicUrlAsync(@Url String fileUrl);
// ResponseBody 转换成输入流转存
ResponseBody body = response.body();
long fileSize = body.contentLength();
InputStream inputStream = body.byteStream();

@Path:URL占位符,用于替换和动态更新,相应的参数必须使用相同的字符串被@Path进行注释
@GET("group/{id}/users")    //最终的url:http://baseurl/group/groupId/users
Call<List<User>> groupList(@Path("id") int groupId);
//等同于:
@GET
Call<List<User>> groupListUrl(@Url String url); // url:http://baseurl/group/groupId/users

@Query,@QueryMap:查询参数,用于GET查询,需要注意的是@QueryMap可以约定是否需要encode
@GET("group/users")        //最终的url:http://baseurl/group/users?id=groupId
Call<List<User>> groupList(@Query("id") int groupId);
Call<List<News>> getNews((@QueryMap(encoded=true) Map<String, String> options);

@Body:  用于POST请求体,将实例对象根据转换方式转换为对应的json字符串参数,这个转化方式是GsonConverterFactory定义的。
@POST("add")
Call<List<User>> addUser(@Body User user);

@Field@FieldMap: Post方式传递简单的键值对,需要添加@FormUrlEncoded表示表单提交Content-Type:application/x-www-form-urlencoded
@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);

@Part@PartMap:用于POST文件上传,其中@Part MultipartBody.Part代表文件,@Part("description") RequestBody代表参数
需要添加@Multipart表示支持文件上传的表单,Content-Type: multipart/form-data

@Multipart
@POST("upload")
Call<ResponseBody> upload(@Part("description") RequestBody description, @Part MultipartBody.Part file);

// use the FileUtils to get the actual file by fileUri
File file = FileUtils.getFile(this, fileUri);

RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file); // 以文件产生RequestBody对象
MultipartBody.Part body = MultipartBody.Part.createFormData("picture", file.getName(), requestFile); // 从RequestBody对象生成MultipartBody.Part对象

String descriptionString = "hello, this is description speaking";
RequestBody description = RequestBody.create(MediaType.parse("multipart/form-data"), descriptionString); // 参数信息

传入body、description变量至upload()方法,形如:
×××.upload(description ,body)                 

@Header:header处理,不能被互相覆盖,用于修饰参数,


@GET("user")
Call<User> getUser(@Header("Authorization") String authorization)   //动态设置Header值

@Headers("Authorization: authorization")  //静态设置Header值,authorization就是上面方法里传进来变量的值
@GET("widget/list")
Call<User> getUser()

@Headers 用于修饰方法,用于设置多个Header值:
@Headers({
    "Accept: application/vnd.github.v3.full+json",
    "User-Agent: Retrofit-Sample-App"
})
@GET("users/{username}")
Call<User> getUser(@Path("username") String username);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值