博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Retrofit
阅读量:4589 次
发布时间:2019-06-09

本文共 5905 字,大约阅读时间需要 19 分钟。

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
> 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实现类对象,负责连接代理类和委托类的中间类

关于动态代理的详细介绍,可以查看 、。

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

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

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

1 // 调用代理对象的每个函数实际最终都是调用了InvocationHandler的invoke函数2 @Override3 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
>() { 4 @Override 5 public void onCompleted() { 6 7 } 8 9 @Override10 public void onError(Throwable e) {11 12 }13 14 @Override15 public void onNext(List
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 create(Class
clazz) {10 // 可做缓存对象操作11 T t = createApi(clazz);12 return t;13 }14 15 protected abstract
T createApi(Class
clazz);16 17 protected RepositoryProxy.Builder getProxyBuilder(){18 return new RepositoryProxy.Builder(){19 @Override20 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 createApi(Class
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 create(Class
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 }

 

附录

转载于:https://www.cnblogs.com/CharlesGrant/p/5803846.html

你可能感兴趣的文章
redis Sorted set 相关命令
查看>>
redis Set相关命令
查看>>
基于物品的协同过滤(ItemCF)
查看>>
基于用户的协同过滤(UserCF)
查看>>
运行Storm实例
查看>>
MapReduce各个执行阶段
查看>>
Shuffle过程详解
查看>>
微软云数据库SQL Azure
查看>>
Amazon DynamoDB
查看>>
云数据库概念
查看>>
云数据库与其他数据库的关系
查看>>
HBase 表和Region
查看>>
HBase功能组件
查看>>
UMP系统架构 RabbitMQ
查看>>
UMP系统架构 Mnesia
查看>>
UMP系统架构 Controller服务器
查看>>
UMP系统架构 Zookeeper
查看>>
HBase+Redis
查看>>
UMP系统架构 LVS
查看>>
Store工作原理
查看>>