Retrofit2的分享

Retrofit2是一个网络框架,基于OkHttp3框架封装的网络框架。

大致理解,实现一个Api对应的接口,调用Retrofit.create 方法,通过动态代理模式生成对应的代理service,并加入okhttp的请求队列中,之后可以调用对应的方法进行请求。

创建service的方式:如果想调用同步的请求,只需调用execute方法,而enqueue则会调用一个异步请求。

优点:1.降低耦合度,api之间互不干扰      2.代码风格:使用注解方式,代码简洁(相同的还有ButterKnife,以及degger,EventBus等框架同样是使用注解)       3.采用构建者模式以及动态代理模式,更灵活

Retrofit2使用流程

1初始化Retrofit(构建者模式)

Retrofit singleton;  
//拦截  用于输出LOG  将请求以及返回值以log形式打印出来
                    HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
                        @Override
                        public void log(String message) {
                            Log.i("tag", "log: ========" + message);
                        }
                    }).setLevel(HttpLoggingInterceptor.Level.BODY);
                    HttpLoggingInterceptor interceptor =new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
                        @Override
                        public void log(String message) {
                            Log.i("tag", "log: ========" + message);
                        }
                    }).setLevel(HttpLoggingInterceptor.Level.BODY);
//将拦截器add给OkhttpClient  在不设置OkHttpclient的情况下 retrofit会使用默认的client
                    OkHttpClient okHttpClient = new OkHttpClient.Builder()
                            .writeTimeout(10, TimeUnit.SECONDS)
                            .addInterceptor(interceptor)
                            .build();
                    singleton = new Retrofit.Builder()
                            .baseUrl(host)
                            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())//支持rxandroid使用的 需要依赖另外的框架
                            .addConverterFactory(GsonConverterFactory.create())
//支持gson解析使用的 需要依赖另外的框架  compile 'com.squareup.retrofit2:converter-gson:2.2.0'
                            .client(okHttpClient)
                            .build();
2.创建对应的api接口
public interface NewsApiService {
  
/**
 * 参数过多
 */
@GET("users/stven0king/repos")
Call<String> getNewsByMap(@QueryMap Map<String, String> params);
}
详细的注解使用方式  http://blog.csdn.net/xiangjai/article/details/51452217
http://www.open-open.com/lib/view/open1453552147323.html
3.api进行请求
NewsApiService newsApiService  = retrofit.create(NewsApiService.class);
Map<String,String> map=new HashMap<>();
map.put("a","a");
//get 参数map
Call<String> newsByMap = newsApiService.getNewsByMap(map);
newsByMap.enqueue(new Callback<String>() {
    @Override
    public void onResponse(Call<String> call, Response<String> response) {

    }

    @Override
    public void onFailure(Call<String> call, Throwable t) {

    }
});
每次生成的api对应的call只能使用一次,支持取消等方法 如果想调用同步的请求,只需调用execute方法,而enqueue则会调用一个异步请求


二:部分源码解析

1.动态代理模式   动态生成对应的代理类,更灵活简便(反射的原理) 并且可以在执行委托类方法时,统一增加另外的处理代码

public interface TestInterface {

    void get();
    void post();
}
public class CustomHandler implements InvocationHandler{
    private TestInterface obj;

    public CustomHandler(TestInterface obj) {
        this.obj = obj;
    }

    @Override
    public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
        Log.d("tag", "invoke() called with: o = [" + o + "], method = [" + method + "], objects = [" + objects + "]");
        return method.invoke(this.obj,objects);
    }
}
TestInterface realSub=new RealSub();
CustomHandler handler=new CustomHandler(realSub);
TestInterface proxyInstance = (TestInterface) Proxy.newProxyInstance(realSub.getClass().getClassLoader(), realSub.getClass().getInterfaces(), handler);
proxyInstance.get();
proxyInstance.post();

Retrofit2中的源码

public <T> T create(final Class<T> service) {
  Utils.validateServiceInterface(service);//检查接口是否符合规则
  if (validateEagerly) {
    eagerlyValidateMethods(service);//检查接口是否符合规则
  }
  return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
      new InvocationHandler() {
        private final Platform platform = Platform.get();

        @Override public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
          // If the method is a method from Object then defer to normal invocation.
          if (method.getDeclaringClass() == Object.class) {
            return method.invoke(this, args);
          }
          if (platform.isDefaultMethod(method)) {
            return platform.invokeDefaultMethod(method, service, proxy, args);
          }
	//从缓存中取出调用的方法,并生成对应的okhttp的请求,调用请求方法的时候,返回请求结果
          ServiceMethod<Object, Object> serviceMethod =
              (ServiceMethod<Object, Object>) loadServiceMethod(method);
          OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
          return serviceMethod.callAdapter.adapt(okHttpCall);
        }
      });
}

private void eagerlyValidateMethods(Class<?> service) {
  Platform platform = Platform.get();
  for (Method method : service.getDeclaredMethods()) {
    if (!platform.isDefaultMethod(method)) {
      loadServiceMethod(method);
    }
  }
}
//将加载的类中的方法加入map的缓存中。
ServiceMethod<?, ?> loadServiceMethod(Method method) {
  ServiceMethod<?, ?> result = serviceMethodCache.get(method);
  if (result != null) return result;

  synchronized (serviceMethodCache) {
    result = serviceMethodCache.get(method);
    if (result == null) {
      result = new ServiceMethod.Builder<>(this, method).build();
      serviceMethodCache.put(method, result);
    }
  }
  return result;
}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值