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/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;

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,340评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,762评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,329评论 0 329
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,678评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,583评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,995评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,493评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,145评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,293评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,250评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,267评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,973评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,556评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,648评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,873评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,257评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,809评论 2 339

推荐阅读更多精彩内容