Retrofit2.0使用详解

举报
yechaoa 发表于 2022/05/30 22:33:29 2022/05/30
【摘要】 综述   retrofit是由square公司开发的。square在github上发布了很多优秀的Android开源项目。例如:otto(事件总线),leakcanary(排查内存泄露),android-times-square(日历控件),dagger(依赖注入),picasso(异步加载图片),okhttp(网络请求),ret...

综述

  retrofit是由square公司开发的。square在github上发布了很多优秀的Android开源项目。例如:otto(事件总线),leakcanary(排查内存泄露),android-times-square(日历控件),dagger(依赖注入),picasso(异步加载图片),okhttp(网络请求),retrofit(网络请求)等等。更多square上的开源项目我们可以去square的GitHub进行查看。这次就来介绍一下retrofit的一些基本用法。retrofit是REST安卓客户端请求库。使用retrofit可以进行GET,POST,PUT,DELETE等请求方式。下面就来看一下retrofit的基本用法。

Retrofit使用方法

  由于retrofit2.0与先前版本的差别还是比较大,对于不同版本之间的差异在这里就不在进行详细区别。下面的例子也是针对于retrofit2.0进行介绍的。retrofit2.0它依赖于OkHttp,而且这部分也不再支持替换。在这里我们也不需要显示的导入okHttp,在retrofit中已经导入okhttp3。


  
  1. <dependency>
  2. <groupId>com.squareup.okhttp3</groupId>
  3. <artifactId>mockwebserver</artifactId>
  4. <scope>test</scope>
  5. </dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

  在下面的例子当中采用与GitHub一些相关api进行演示。在这里首先需要添加访问网络的权限。

<uses-permission android:name="android.permission.INTERNET"/>
 
 
  • 1
  • 1

简单示例

添加Gradle依赖项

  在这里我们最好查看一下retrofit的官网添加最新依赖。

compile 'com.squareup.retrofit2:retrofit:2.0.1'
 
 
  • 1
  • 1

创建API接口

  在retrofit中通过一个Java接口作为http请求的api接口。


  
  1. public interface GitHubApi {
  2. @GET("repos/{owner}/{repo}/contributors")
  3. Call<ResponseBody> contributorsBySimpleGetCall(@Path("owner") String owner, @Path("repo") String repo);
  4. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

创建retrofit实例

  在这里baseUrl是在创建retrofit实力的时候定义的,我们也可以在API接口中定义完整的url。在这里建议在创建baseUrl中以”/”结尾,在API中不以”/”开头和结尾。


  
  1. Retrofit retrofit = new Retrofit.Builder()
  2. .baseUrl("https://api.github.com/")
  3. .build();
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

调用API接口

  在调用API接口请求后,获得一个json字符串,通过Gson进行解析,获得login以及contributions。


  
  1. GitHubApi repo = retrofit.create(GitHubApi.class);
  2. Call<ResponseBody> call = repo.contributorsBySimpleGetCall(mUserName, mRepo);
  3. call.enqueue(new Callback<ResponseBody>() {
  4. @Override
  5. public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
  6. try {
  7. Gson gson = new Gson();
  8. ArrayList<Contributor> contributorsList = gson.fromJson(response.body().string(), new TypeToken<List<Contributor>>(){}.getType());
  9. for (Contributor contributor : contributorsList){
  10. Log.d("login",contributor.getLogin());
  11. Log.d("contributions",contributor.getContributions()+"");
  12. }
  13. } catch (IOException e) {
  14. e.printStackTrace();
  15. }
  16. }
  17. @Override
  18. public void onFailure(Call<ResponseBody> call, Throwable t) {
  19. }
  20. });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

效果展示

  这样就完成了一个http请求,上面请求的完整地址为:https://api.github.com/repos/square/retrofit/contributors 
  然后我们看一下运行结果: 
这里写图片描述

取消请求

  我们可以终止一个请求。终止操作是对底层的httpclient执行cancel操作。即使是正在执行的请求,也能够立即终止。

call.cancel();
 
 
  • 1
  • 1

转换器

  在上面的例子中通过获取ResponseBody后,我们自己使用Gson来解析接收到的Json格式数据。在Retrofit中当创建一个Retrofit实例的时候可以为其添加一个Json转换器,这样就会自动将Json格式的响应体转换为所需要的Java对象。那么先来看一下如何根据已有的Json格式数据如何生成Java对象。当然我们可以根据已知的数据手动创建Java对象,也可以通过工具更具Json格式为我们自动生成Java对象。

自动生成Java对象

  在这里介绍两种根据Json数据自动生成Java对象的工具。

jsonschema2pojo

  可以通过访问jsonschema2pojo网站。先来看一下它的使用方法。 
这里写图片描述
  上面配置中所选注解若是使用的Gson解析,可以选择Gson,当然没有也是可以的。对于@Generated注解若是需要保留的话添加如下依赖,也可以直接删除@Generated注解,没有任何影响。

compile 'org.glassfish:javax.annotation:10.0-b28'
 
 
  • 1
  • 1

GsonFormat

  GsonFormat是AndroidStudio中的一个插件,在AndroidStudio的插件选项中直接搜索安装这个插件即可。在这里看一下是如何使用这个插件的。 
这里写图片描述

添加转换器

  在这里我们需要为retrofit添加gson转换器的依赖。添加过converter-gson后不用再添加gson库。在converter-gson中已经包含gson。

compile 'com.squareup.retrofit2:converter-gson:2.0.1'
 
 
  • 1
  • 1

  在这里先创建一个Java类Contributor,用来保存接收到的数据。


  
  1. public class Contributor {
  2. private String login;
  3. private Integer contributions;
  4. public String getLogin() {
  5. return login;
  6. }
  7. public void setLogin(String login) {
  8. this.login = login;
  9. }
  10. public Integer getContributions() {
  11. return contributions;
  12. }
  13. public void setContributions(Integer contributions) {
  14. this.contributions = contributions;
  15. }
  16. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

  这时候修改我们的API接口。


  
  1. @GET("repos/{owner}/{repo}/contributors")
  2. Call<List<Contributor>> contributorsByAddConverterGetCall(@Path("owner") String owner, @Path("repo") String repo);
  • 1
  • 2
  • 1
  • 2

  创建retrofit实例,我们通过addConverterFactory指定一个factory来对响应反序列化,在这里converters被添加的顺序将是它们被Retrofit尝试的顺序。


  
  1. Retrofit retrofit = new Retrofit.Builder()
  2. .baseUrl("https://api.github.com/")
  3. .addConverterFactory(GsonConverterFactory.create())
  4. .build();
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

  调用上面所修改的API接口。


  
  1. GitHubApi repo = retrofit.create(GitHubApi.class);
  2. Call<List<Contributor>> call = repo.contributorsByAddConverterGetCall(mUserName, mRepo);
  3. call.enqueue(new Callback<List<Contributor>>() {
  4. @Override
  5. public void onResponse(Call<List<Contributor>> call, Response<List<Contributor>> response) {
  6. List<Contributor> contributorList = response.body();
  7. for (Contributor contributor : contributorList){
  8. Log.d("login", contributor.getLogin());
  9. Log.d("contributions", contributor.getContributions() + "");
  10. }
  11. }
  12. @Override
  13. public void onFailure(Call<List<Contributor>> call, Throwable t) {
  14. }
  15. });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

  最后在来看一下运行结果。 
这里写图片描述
  retrofit不仅仅只支持gson,还支持其他许多json解析库。以下版本号需要与retrofit版本号保持一致,并且以retrofit官网给出的版本号为准。

  • Gsoncompile 'com.squareup.retrofit2:converter-gson:2.0.1'
  • Jacksoncompile 'com.squareup.retrofit2:converter-jackson:2.0.1'
  • Moshicompile 'com.squareup.retrofit2:converter-moshi:2.0.1'
  • Protobufcompile 'com.squareup.retrofit2:converter-protobuf:2.0.1'
  • Wirecompile 'com.squareup.retrofit2:converter-wire:2.0.1'
  • Simple XMLcompile 'com.squareup.retrofit2:converter-simplexml:2.0.1'
  • Scalars (primitives, boxed, and String): compile 'com.squareup.retrofit2:converter-scalars:2.0.1'

增加日志信息

  在retrofit2.0中是没有日志功能的。但是retrofit2.0中依赖OkHttp,所以也就能够通过OkHttp中的interceptor来实现实际的底层的请求和响应日志。在这里我们需要修改上一个retrofit实例,为其自定自定义的OkHttpClient。代码如下:


  
  1. HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
  2. httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
  3. OkHttpClient okHttpClient = new OkHttpClient.Builder()
  4. .addInterceptor(httpLoggingInterceptor)
  5. .build();
  6. Retrofit retrofit = new Retrofit.Builder().addCallAdapterFactory(RxJavaCallAdapterFactory.create())
  7. .client(okHttpClient)
  8. .baseUrl("https://api.github.com/")
  9. .addConverterFactory(GsonConverterFactory.create())
  10. .build();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

  还需要添加如下依赖。

compile 'com.squareup.okhttp3:logging-interceptor:3.1.2'
 
 
  • 1
  • 1

  其他代码没有任何变化,我们来看一下运行结果。 
这里写图片描述

添加请求头

  我们可以通过@Headers来添加请求头。


  
  1. @Headers({
  2. "Accept: application/vnd.github.v3.full+json",
  3. "User-Agent: RetrofitBean-Sample-App",
  4. "name:ljd"
  5. })
  6. @GET("repos/{owner}/{repo}/contributors")
  7. Call<List<Contributor>> contributorsAndAddHeader(@Path("owner") String owner,@Path("repo") String repo);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

  运行结果。 
这里写图片描述

同步请求

  在这里我们可以直接通过call.execute()执行一个同步请求,由于不允许在主线程中进行网络请求操作,所以我们需要再子线程中进行执行。


  
  1. new Thread(new Runnable() {
  2. @Override
  3. public void run() {
  4. try {
  5. Response<List<Contributor>> response = call.execute();
  6. List<Contributor> contributorsList = response.body();
  7. for (Contributor contributor : contributorsList){
  8. Log.d("login",contributor.getLogin());
  9. Log.d("contributions",contributor.getContributions()+"");
  10. }
  11. } catch (IOException e) {
  12. e.printStackTrace();
  13. }
  14. }
  15. }).start();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

  在这里看一下运行结果。 
这里写图片描述

clone

  在这里无论是同步操作还是异步操作每一个call对象实例只能被执行一次。多次执行抛出如下异常。 
这里写图片描述
  在这里如果我们的request和respone都是一一对应的。我们通过Clone方法创建一个一模一样的实例,并且它的开销也是很小的。


  
  1. Call<List<Contributor>> cloneCall = call.clone();
  2. cloneCall.execute();
  • 1
  • 2
  • 1
  • 2

get请求

  在前面的一些例子当中我们都是采用get请求。当然我们也可以为URL指定查询参数。使用@Query即可。


  
  1. @GET("search/repositories")
  2. Call<RetrofitBean> queryRetrofitByGetCall(@Query("q")String owner,
  3. @Query("since")String time,
  4. @Query("page")int page,
  5. @Query("per_page")int per_Page);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

  当我们的参数过多的时候我们可以通过@QueryMap注解和map对象参数来指定每个表单项的Key,value的值。


  
  1. @GET("search/repositories")
  2. Call<RetrofitBean> queryRetrofitByGetCallMap(@QueryMap Map<String,String> map);
  • 1
  • 2
  • 1
  • 2

  下面的call对象实例为上面api中所返回call对象。更具所返回的json数据所创建的实体类在这里就不在贴出代码,下载源码详细查看。


  
  1. call.enqueue(new Callback<RetrofitBean>() {
  2. @Override
  3. public void onResponse(Call<RetrofitBean> call, Response<RetrofitBean> response) {
  4. RetrofitBean retrofit = response.body();
  5. List<Item> list = retrofit.getItems();
  6. if (list == null)
  7. return;
  8. Log.d(TAG, "total:" + retrofit.getTotalCount());
  9. Log.d(TAG, "incompleteResults:" + retrofit.getIncompleteResults());
  10. Log.d(TAG, "----------------------");
  11. for (Item item : list) {
  12. Log.d(TAG, "name:" + item.getName());
  13. Log.d(TAG, "full_name:" + item.getFull_name());
  14. Log.d(TAG, "description:" + item.getDescription());
  15. Owner owner = item.getOwner();
  16. Log.d(TAG, "login:" + owner.getLogin());
  17. Log.d(TAG, "type:" + owner.getType());
  18. }
  19. }
  20. @Override
  21. public void onFailure(Call<RetrofitBean> call, Throwable t) {
  22. }
  23. });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

  上面请求中的完整连接为: https://api.github.com/search/repositories?q=retrofit&since=2016-03-29&page=1&per_page=3,运行结果如下。 
这里写图片描述

  在Retrofit 2.0添加了一个新的注解:@Url,它允许我们直接传入一个请求的URL。这样以来我们可以将上一个请求的获得的url直接传入进来。方便了我们的操作。


  
  1. @GET
  2. Call<List<Contributor>> repoContributorsPaginate(@Url String url);
  • 1
  • 2
  • 1
  • 2

Form encoded和Multipart

Form encoded

  我们可以使用@FormUrlEncoded注解来发送表单数据。使用 @Field注解和参数来指定每个表单项的Key,value为参数的值。


  
  1. @FormUrlEncoded
  2. @POST("user/edit")
  3. Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

  当我们有很多个表单参数时可以通过@FieldMap注解和Map对象参数来指定每个表单项的Key,value的值。


  
  1. @FormUrlEncoded
  2. @POST("user/edit")
  3. Call<User> updateUser(@FieldMap Map<String,String> fieldMap);
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

Multipart

  我们还可以通过@Multipart注解来发送Multipart数据。通过@Part注解来定义需要发送的文件。


  
  1. @Multipart
  2. @PUT("/user/photo")
  3. User updateUser(@Part("photo") TypedFile photo, @Part("description") TypedString description);
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

Retrofit与RxJava结合

  Retrofit能够与RxJava进行完美结合。下面就来看一下Retrofit与RxJava是如何结合在一起的。对于RxJava在这就不在进行详细介绍,对于RXJava的使用可以参考附录里面给出链接。 
  首先我们需要添加如下依赖。


  
  1. compile 'com.squareup.retrofit2:adapter-rxjava:2.0.1'
  2. compile 'io.reactivex:rxandroid:1.1.0'
  • 1
  • 2
  • 1
  • 2

  创建retrofit对象实例时,通过addCallAdapterFactory来添加对RxJava的支持。


  
  1. HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
  2. httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
  3. OkHttpClient okHttpClient = new OkHttpClient.Builder()
  4. .addInterceptor(httpLoggingInterceptor)
  5. .build();
  6. Retrofit retrofit = new Retrofit.Builder()
  7. .client(okHttpClient)
  8. .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
  9. .addConverterFactory(GsonConverterFactory.create())
  10. .baseUrl("https://api.github.com/")
  11. .build();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

  使用Observable创建一个API接口。


  
  1. @GET("repos/{owner}/{repo}/contributors")
  2. Observable<List<Contributor>> contributorsByRxJava(@Path("owner") String owner,@Path("repo") String repo);
  • 1
  • 2
  • 1
  • 2

  下面来调用这个API接口。

private CompositeSubscription mSubscriptions = new CompositeSubscription();
 
 
  • 1
  • 1

  
  1. mSubscriptions.add(
  2. mGitHubService.contributorsByRxJava(mUserName, mRepo)
  3. .subscribeOn(Schedulers.io())
  4. .observeOn(AndroidSchedulers.mainThread())
  5. .subscribe(new Observer<List<Contributor>>() {
  6. @Override
  7. public void onCompleted() {
  8. }
  9. @Override
  10. public void onError(Throwable e) {
  11. }
  12. @Override
  13. public void onNext(List<Contributor> contributors) {
  14. for (Contributor c : contributors) {
  15. Log.d("TAG", "login:" + c.getLogin() + " contributions:" + c.getContributions());
  16. }
  17. }
  18. }));
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

  下面来看一下运行结果。 
这里写图片描述
  如果我们想要查看所有contributor的信息,首先我们需要向gitHub请求获取到所有contributor,然后再通过获得contributor进行依次向github请求获取contributor的信息,在这时候我们使用RxJava也就非常方便了。下面看一下如何操作的。 
  首先再添加一个API接口。


  
  1. @GET("repos/{owner}/{repo}/contributors")
  2. Observable<List<Contributor>> contributorsByRxJava(@Path("owner") String owner,
  3. @Path("repo") String repo);
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

  下面在看一下是如何进行根据获得的contributor来查看contributor的信息。


  
  1. mSubscriptions.add(mGitHubService.contributorsByRxJava(mUserName, mRepo)
  2. .flatMap(new Func1<List<Contributor>, Observable<Contributor>>() {
  3. @Override
  4. public Observable<Contributor> call(List<Contributor> contributors) {
  5. return Observable.from(contributors);
  6. }
  7. })
  8. .flatMap(new Func1<Contributor, Observable<Pair<User, Contributor>>>() {
  9. @Override
  10. public Observable<Pair<User, Contributor>> call(Contributor contributor) {
  11. Observable<User> userObservable = mGitHubService.userByRxJava(contributor.getLogin())
  12. .filter(new Func1<User, Boolean>() {
  13. @Override
  14. public Boolean call(User user) {
  15. return !isEmpty(user.getName()) && !isEmpty(user.getEmail());
  16. }
  17. });
  18. return Observable.zip(userObservable,
  19. Observable.just(contributor),
  20. new Func2<User, Contributor, Pair<User, Contributor>>() {
  21. @Override
  22. public Pair<User, Contributor> call(User user, Contributor contributor) {
  23. return new Pair<>(user, contributor);
  24. }
  25. });
  26. }
  27. })
  28. .subscribeOn(Schedulers.newThread())
  29. .observeOn(AndroidSchedulers.mainThread())
  30. .subscribe(new Observer<Pair<User, Contributor>>() {
  31. @Override
  32. public void onCompleted() {
  33. }
  34. @Override
  35. public void onError(Throwable e) {
  36. }
  37. @Override
  38. public void onNext(Pair<User, Contributor> pair) {
  39. User user = pair.first;
  40. Contributor contributor = pair.second;
  41. Log.d(TAG, "name:" + user.getName());
  42. Log.d(TAG, "contributions:" + contributor.getContributions());
  43. Log.d(TAG, "email:" + user.getEmail());
  44. }
  45. }));
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

  最后在来看下运行结果。 
这里写图片描述

Retrofit设置缓存

对Retrofit设置缓存,由于Retrofit是对OkHttp的封装,所以我们可以直接通过OkHttpClient着手。也就是为OkHttp设置缓存。设置缓存代码如下所示。


  
  1. private OkHttpClient getCacheOkHttpClient(Context context){
  2. final File baseDir = context.getCacheDir();
  3. final File cacheDir = new File(baseDir, "HttpResponseCache");
  4. Timber.e(cacheDir.getAbsolutePath());
  5. Cache cache = new Cache(cacheDir, 10 * 1024 * 1024); //缓存可用大小为10M
  6. Interceptor REWRITE_CACHE_CONTROL_INTERCEPTOR = chain -> {
  7. Request request = chain.request();
  8. if(!NetWorkUtils.isNetWorkAvailable(context)){
  9. request = request.newBuilder()
  10. .cacheControl(CacheControl.FORCE_CACHE)
  11. .build();
  12. }
  13. Response originalResponse = chain.proceed(request);
  14. if (NetWorkUtils.isNetWorkAvailable(context)) {
  15. int maxAge = 60; //在线缓存一分钟
  16. return originalResponse.newBuilder()
  17. .removeHeader("Pragma")
  18. .removeHeader("Cache-Control")
  19. .header("Cache-Control", "public, max-age=" + maxAge)
  20. .build();
  21. } else {
  22. int maxStale = 60 * 60 * 24 * 4 * 7; //离线缓存4周
  23. return originalResponse.newBuilder()
  24. .removeHeader("Pragma")
  25. .removeHeader("Cache-Control")
  26. .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
  27. .build();
  28. }
  29. };
  30. return new OkHttpClient.Builder()
  31. .addNetworkInterceptor(REWRITE_CACHE_CONTROL_INTERCEPTOR)
  32. .addInterceptor(REWRITE_CACHE_CONTROL_INTERCEPTOR)
  33. .cache(cache)
  34. .build();
  35. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

总结

  在retrofit的使用中,对于文件你上传与下载,并没有为我们提供进度更新的接口,在这里就需要我们自己处理了。在下面的例子中给出一个文件下载的例子,并且对下载进度更新通过logcat打印出来。可以下载进行查看。到这里retrofit的基本用法也就介绍完了,对于retrofit更多的好处在使用中我们可以慢慢体会。

原文:http://blog.csdn.net/ljd2038/article/details/51046512

文章来源: blog.csdn.net,作者:yechaoa,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/yechaoa/article/details/77434307

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。