美文网首页
Retrofit2的分享

Retrofit2的分享

作者: 1a4d4ac5a222 | 来源:发表于2017-03-24 11:33 被阅读0次

    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/51452217http://www.open-open.com/lib/view/open1453552147323.html3.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;

    }

    相关文章

      网友评论

          本文标题:Retrofit2的分享

          本文链接:https://www.haomeiwen.com/subject/daoxottx.html