Retrofit

Retrofit 不算是一个网络库,它应该算是封装了 okhttp ,retrofit的最大特点就是解耦,要解耦就需要大量的设计模式,然后为我们提供了一个友好的接口的一个工具库吧。

1、创建Retrofit对象:

builder 模式,外观模式(门面模式)

外观模式具有高内聚、低耦合的特性,对外提供简单统一的接口,隐蔽了子系统具体的实现、隔离变化。

在封装某些特定功能时,比如下载module,外观模式是一种很好的设计规范。即下载module与其他module通信时通过DownloadManager对象进行。Retrofit是整个库的一个入口类,Retrofit库的使用基本都是围绕着这个类。

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

2、定义api

public interface StudentApi {

    /**
     * 学生列表 for age
     */
    @POST("/student/studentList")
    Observable<List<Student>> selectStudentListForAge(@Field("age") int age);

}

获取 API 实例:通过动态代理模式:使用动态代理,因为对接口的所有方法的调用都会集中转发到 InvocationHandler#invoke 函数中,我们可以集中进行处理,更方便了。

// 在请求,初始化StudentApi
StudentApi  mStudentApi = retrofit.create(StudentApi.class);

调用create()方法,通过 Proxy 类静态函数生成代理对象StudentApi并返回:

Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h);

loader表示类加载器
interfaces表示委托类的接口,生成代理类时需要实现这些接口
hInvocationHandler实现类对象,负责连接代理类和委托类的中间类

关于动态代理的详细介绍,可以查看 codeKK 公共技术点之 Java 动态代理这篇文章。

1 // 调用其方法时,调用了Retrofit的动态代理的InvocationHandler对象MethodHandler对象
2  mStudentApi.selectStudentListForAge(18)....;

执行该方法后,调用了InvocationHandler对象的invoke方法。

在invoke方法上,处理并返回一个http请求对象,在此,还可以做些有用的操作,例如统计执行时间、进行初始化和清理、对接口调用进行检查等。

1 // 调用代理对象的每个函数实际最终都是调用了InvocationHandler的invoke函数
2 @Override
3 public Object invoke(Object proxy, Method method, Object[] args)

proxy 通过 Proxy.newProxyInstance() 生成的代理类对象。
method 表示代理对象被调用的函数。
args 表示代理对象被调用的函数的参数。

1、当执行subscribe的时候,整个http请求执行。

2、调用

mStudentApi.selectStudentListForAge(18)

返回对象的execute()enqueue(Callback<T> callback)方法,就能发送一个Http请求了:

 1 mStudentApi.selectStudentListForAge(18)
 2 .observeOn(AndroidSchedulers.mainThread())
 3                 .subscribe(new Subscriber<List<Student>>() {
 4                     @Override
 5                     public void onCompleted() {
 6
 7                     }
 8
 9                     @Override
10                     public void onError(Throwable e) {
11
12                     }
13
14                     @Override
15                     public void onNext(List<Student> studentList) {
16
17                     }
18                 }));

熟练使用annotation、reflect,造一个retrofit雏形。

定义post、get、field等:

 1 import java.lang.annotation.Documented;
 2 import java.lang.annotation.Retention;
 3 import java.lang.annotation.Target;
 4 import static java.lang.annotation.ElementType.METHOD;
 5 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 6
 7 @Documented
 8 @Target(METHOD)
 9 @Retention(RUNTIME)
10 public @interface POST {
11     String value() default "";
12
13     boolean requestSync() default false;
14 }

POST

 1 import java.lang.annotation.Documented;
 2 import java.lang.annotation.Retention;
 3 import java.lang.annotation.Target;
 4 import static java.lang.annotation.ElementType.METHOD;
 5 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 6
 7 @Documented
 8 @Target(METHOD)
 9 @Retention(RUNTIME)
10 public @interface GET {
11     String value() default "";
12 }

GET

 1 import java.lang.annotation.Documented;
 2 import java.lang.annotation.Retention;
 3 import java.lang.annotation.Target;
 4 import static java.lang.annotation.ElementType.PARAMETER;
 5 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 6
 7 @Documented
 8 @Target(PARAMETER)
 9 @Retention(RUNTIME)
10 public @interface Field {
11     String value();
12
13     boolean encoded() default false;
14 }

Field

创建BaseRetrofit对象,作为基类,其子类继承并重写createApi方法,在方法中,创建并配置retrofit对象。

 1 import java.util.Map;
 2 import java.util.concurrent.ConcurrentHashMap;
 3
 4 public abstract class BaseRetrofit {
 5
 6         // http请求
 7     SimpleRepository repository;
 8
 9     public <T> T create(Class<T> clazz) {
10                // 可做缓存对象操作
11         T t = createApi(clazz);
12         return t;
13     }
14
15     protected abstract <T> T createApi(Class<T> clazz);
16
17     protected RepositoryProxy.Builder getProxyBuilder(){
18         return new RepositoryProxy.Builder(){
19             @Override
20             public RepositoryProxy build() {
21                 RepositoryProxy proxy = super.build();
22
23                 setRepository(proxy.getRepository());
24
25                 return proxy;
26             }
27         };
28     }
29
30         protected void setRepository(SimpleRepository repository) {
31         this.repository = repository;
32     }
33
34     public SimpleRepository getRepository() {
35         return repository;
36     }
37
38 }

创建子类:使用时,new StudentRetrofit().create(StudentApi.class);生成动态代理类,通过RepositoryProxy 代理操作。

 1 public class StudentRetrofit extends BaseRetrofit {
 2
 3     @Override
 4     protected  <T> T createApi(Class<T> clazz) {
 5         RepositoryProxy retrofit = getProxyBuilder().baseurl("http://www.baidu.com")
 6                                                     .build();
 7
 8         return retrofit.create(clazz);
 9     }
10 }

RepositoryProxy 代理操作:

 1 public class RepositoryProxy {
 2     public <T> T create(Class<T> clazz) {
 3         if (!clazz.isInterface()) {
 4             throw new RuntimeException("retrofit Service not interface");
 5         }
 6
 7         return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class[]{clazz}, new ApiProxy(this));
 8     }
 9
10 }

InvocationHandler对象:

 1 public class ApiProxy implements InvocationHandler {
 2
 3 @Override
 4     public Object invoke(Object proxy, Method method, Object... args) throws Throwable {
 5
 6         // If the method is a method from Object then defer to normal invocation.
 7         if (method.getDeclaringClass() == Object.class) {
 8             return method.invoke(this, args);
 9         }
10
11         // 返回http请求对象
12         return post(method, args);
13     }
14
15 }

附录

retrofit官方文档
用 Retrofit 2 简化 HTTP 请求
使用Retrofit请求API数据
Retrofit2 更新指南
RESTful API 设计指南

Android Retrofit 2.0使用

Android Retrofit 2.0 使用-补充篇

Retrofit源码设计模式解析上

Retrofit源码设计模式解析下

使用Retrofit请求API数据-codepath教程

Retrofit源码解析

Retrofit 源码的一个分析与导读

时间: 2024-11-10 01:22:52

Retrofit的相关文章

Retrofit 入门学习

Retrofit 入门学习官方RetrofitAPI 官方的一个例子 public interface GitHubService { @GET("users/{user}/repos") Call<List<Repo>> listRepos(@Path("user") String user); } 这些注解都有一个参数 value,用来配置其路径,比如示例中的 users/{user}/repos, 我们还注意到在构造 Retrofit

Retrofit Token过期自动刷新并重新请求接口

在有心课堂的群里,有网友提出如下场景: 当前开发的 App 遇到一个问题: 当请求某个接口时,由于 token 已经失效,所以接口会报错. 但是产品经理希望 app 能够马上刷新 token ,然后重复请求刚才那个接口,这个过程对用户来说是无感的. 请求 A 接口->服务器返回 token 过期->请求 token 刷新接口->请求 A 接口 我们应该是怎么解决这个问题呢? 经过百度搜索到了相关信息,这里总结下. 本文是采用RxJava + Retrofit来实现网络请求封装. 实现原理

Retrofit——A type-safe HTTP client for Android and Java(The first part)

一,介绍 Retrofit将你的http接口API转换成项目中的一个java的接口. public interface GitHubService { @GET("users/{user}/repos") Call<List<Repo>> listRepos(@Path("user") String user); } Retrofit会自动为上面的Service生成一个实现类. Retrofit retrofit = new Retrofit

Retrofit自定义GsonConverter处理请求错误异常处理

通常从服务端拿到的JSON数据格式大概如下: { "code":1, "message":"查询成功", "detail":{"aa":"123","bb":"123","cc":"123"} } 因此通常我们会定义一个实体类来解析对应的json: public class Response { @Seria

Rxjava+ReTrofit+okHttp深入浅出-终极封装

Rxjava+ReTrofit+okHttp深入浅出-终极封装 背景: 学习Rxjava和retrofit已经很长时间了,功能确实很强大,但是使用起来还是有点复杂,代码的重复性太高,所以决定把基于retrofit和rxjava的处理统一封装起来,实现的功能: 1.Retrofit+Rxjava+okhttp基本使用方法 2.统一处理请求数据格式 3.统一的ProgressDialog和回调Subscriber处理 4.取消http请求 5.预处理http请求 5.返回数据的统一判断 效果: 封装

RxJava 与 Retrofit

RxJava 与 Retrofit

Retrofit+RxJava(1)-在Android Studio中配置

在build.gradle中添加 //加入retrolambda需要的plugin声明 apply plugin: 'me.tatarka.retrolambda' //retrolambda的编译路径依赖 buildscript { dependencies { classpath 'me.tatarka:gradle-retrolambda:3.1.0' } } //让IDE使用用Java8语法解析 android { compileOptions { sourceCompatibility

Retrofit结合RxJava个人使用经验

Retrofit出来也蛮久了,每次听其他小伙伴说起来都是那种吊吊的感觉,所以自己也赶紧加入其中,用完之后感觉真的很棒,当然学习的时候也是遇到不少问题,爽歪歪的感脚.具体该怎么用Retrofit,推荐鸿洋的文章Retrofit2 完全解析 探索与okhttp之间的关系 ,写的比较清楚,我也不多花笔墨在这上面了,下面要说的是我个人使用Retrofit遇到的一些问题. 首先是引用库了,在module的build.gradle文件中添加 compile 'io.reactivex:rxjava:1.1.

第五章 服务熔断(hystrix)+ retrofit底层通信(AsyncHttpclient)

一.集群容错 技术选型:hystrix.(就是上图中熔断器) 熔断的作用: 第一个作用: 假设有两台服务器server1(假设可以处理的请求阈值是1W请求)和server2,在server1上注册了三个服务service1.service2.service3,在server2上注册了一个服务service4,假设service4服务响应缓慢,service1调用service4时,一直在等待响应,那么在高并发下,很快的server1处很快就会达到请求阈值(server1很快就会耗尽处理线程)之后

第七章 springboot + retrofit

retrofit:一套RESTful架构的Android(Java)客户端实现. 好处: 基于注解 提供JSON to POJO,POJO to JSON,网络请求(POST,GET,PUT,DELETE等)封装 可以看做是对HttpClient的再次封装 1.为了做测试,建立了一个新的springboot项目"myboot2",项目结构如下: 1.1.pom.xml 1 <?xml version="1.0" encoding="UTF-8&quo