retrofit的实现原理(一)

转载 2015年07月08日 12:28:24

retrofit框架实现的这么巧妙,虽然我们不需要再造一个轮子,但研究下轮子的实现还是很有帮助的.

retrofit有几个关键的地方.

1.用户自定义的接口和接口方法.(由动态代理创建对象.)

2.converter转换器.(把response转换为一个具体的对象)

3.注解的使用.

 

让我们跟随Api来看吧.

RestAdapter restAdapter = new RestAdapter.Builder().setEndpoint(API_URL).build(); 

  build()其内部实现是这样的:

1
2
3
4
5
6
7
8
public RestAdapter build() {
     if (endpoint == null) {
       throw new IllegalArgumentException("Endpoint may not be null.");
     }
     ensureSaneDefaults();
     return new RestAdapter(endpoint, clientProvider, httpExecutor, callbackExecutor,
         requestInterceptor, converter, profiler, errorHandler, log, logLevel);
   }

  当用户没有设置自定义的converter,client, httpExecutor(http访问执行的线程-->只对异步的retrofit有效.), callBackExecutor(异步的callBack执行的线程), errorHandler, log, RequestInterceptor的时候,就会使用retrofit默认的配置.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
private void ensureSaneDefaults() {
    if (converter == null) {
      converter = Platform.get().defaultConverter();
    }
    if (clientProvider == null) {
      clientProvider = Platform.get().defaultClient();
    }
    if (httpExecutor == null) {
      httpExecutor = Platform.get().defaultHttpExecutor();
    }
    if (callbackExecutor == null) {
      callbackExecutor = Platform.get().defaultCallbackExecutor();
    }
    if (errorHandler == null) {
      errorHandler = ErrorHandler.DEFAULT;
    }
    if (log == null) {
      log = Platform.get().defaultLog();
    }
    if (requestInterceptor == null) {
      requestInterceptor = RequestInterceptor.NONE;
    }
  }
}

  Platform.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private static final Platform PLATFORM = findPlatform();
 
static Platform get() {
  return PLATFORM;
}
 
private static Platform findPlatform() {
  try {
    Class.forName("android.os.Build");//只要android.os.Build的class可以正常找到,证明是在android平台
    if (Build.VERSION.SDK_INT != 0) {
      return new Android();
    }
  catch (ClassNotFoundException ignored) {
  }
 
  if (System.getProperty("com.google.appengine.runtime.version") != null) {
    return new AppEngine();   //google的app Engine平台
  }
 
  return new Base();
}  

retrofit的Android类继承了Platform, 根据android的特性对配置项做了处理.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
private static class Android extends Platform {
    @Override Converter defaultConverter() {
      return new GsonConverter(new Gson());  //默认的转换器是Gson
    }
 
    @Override Client.Provider defaultClient() {
      final Client client;
      if (hasOkHttpOnClasspath()) {  //有okhttp的路径就使用 Okhttp
        client = OkClientInstantiator.instantiate();
      else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD) {
        client = new AndroidApacheClient(); //没有okhttp,且版本小于2.3 使用HttpClient
      else {
        client = new UrlConnectionClient();  //没有okhttp,且版本大于等于2.3 使用urlConnection.
      }
      return new Client.Provider() {
        @Override public Client get() {
          return client;
        }
      };
    }
 
    @Override Executor defaultHttpExecutor() {   //网络访问执行的线程.
      return Executors.newCachedThreadPool(new ThreadFactory() {  //一个cached的线程池.可以复用老线程且线程长时间不用会自动回收. 线程池中线程不够会生成新线程.
        @Override public Thread newThread(final Runnable r) {
          return new Thread(new Runnable() {
            @Override public void run() {
              Process.setThreadPriority(THREAD_PRIORITY_BACKGROUND);    //设置线程的优先级 为最低
              r.run();
            }
          }, RestAdapter.IDLE_THREAD_NAME);
        }
      });
    }
 
    @Override Executor defaultCallbackExecutor() { //异步执行的线程.
      return new MainThreadExecutor();
    }
 
    @Override RestAdapter.Log defaultLog() {  //通过Log.d("Retrofit",String)打印log
      return new AndroidLog("Retrofit");
    }
  }
1
2
3
4
5
6
7
8
private static boolean hasOkHttpOnClasspath() {
  try {
    Class.forName("com.squareup.okhttp.OkHttpClient"); //是否可以找到OkHttpClient类.
    return true;
  catch (ClassNotFoundException ignored) {
  }
  return false;
}

可以发现上面默认的Http的Executor是一个线程池.

而CallBack的Executor是在主线程执行的. 由绑定MainLooper的Handler提交到主线程执行.

1
2
3
4
5
6
7
public final class MainThreadExecutor implements Executor {
  private final Handler handler = new Handler(Looper.getMainLooper()); //关联主线程的Handler
 
  @Override public void execute(Runnable r) {
    handler.post(r);                                 //提交到主线程执行
  }
}
1
2
3
4
public final boolean post(Runnable r)
    {
       return  sendMessageDelayed(getPostMessage(r), 0);
    }
1
2
3
4
5
private static Message getPostMessage(Runnable r) {   //把runnable封装到Message中.
      Message m = Message.obtain();
      m.callback = r;
      return m;
  }

Retrofit 原理 运行机制详解

阅读此篇博客,你需要备Java动态代理的知识、反射和注解相关的知识,不然你阅读可能有些困难回忆Retrofit的适应场景在使用Retrofit的时候,我们经常通常看到有一个用于请求的接口,然后使用Ap...
  • u011692041
  • u011692041
  • 2016年11月06日 18:58
  • 1362

android网络请求框架的学习之路——浅谈对Volley,OkHttp,Retrofit的了解与对比 标签: androidVolleyOkhttpRetrofit网络请求框架

版权声明:本文为博主原创文章,未经博主允许不得转载。            网络请求这个话题基本是所有 App 开发都会遇到的,对于选择什么样的App网络请求框架相信很多人刚开是都会是一脸懵逼的...
  • qq_35114086
  • qq_35114086
  • 2016年11月24日 13:10
  • 752

Android Retrofit框架解析

随着Google对HttpClient的摒弃,和Volley的逐渐没落,OkHttp开始异军突起,而Retrofit则对okHttp进行了强制依赖。Retrofit也是Square公司开发的一款针对A...
  • huaxun66
  • huaxun66
  • 2016年09月26日 21:15
  • 4947

android网络框架retrofit源码解析一

Retrofit的使用就是以下几步:         定义接口,参数声明,Url都通过Annotation指定         通过RestAdapter生成一个接口的实现类(动态代理)    ...
  • jiguangcanhen
  • jiguangcanhen
  • 2014年09月03日 15:02
  • 1786

Volley与Retrofit(OKHttp)使用与区别

Volley使用:    平常我们使用Volley的标准步骤是:         (1)创建一个RequestQueue队列;              RequestQueue mQueue...
  • ysh06201418
  • ysh06201418
  • 2017年05月11日 21:30
  • 758

【Android实战】----基于Retrofit实现多图片/文件、图文上传

一、再次膜拜下RetrofitRetrofit无论从性能还是使用方便性上都很屌!!!,本文不去介绍其运作原理(虽然很想搞明白),后面会出专题文章解析Retrofit的内部原理;本文只是从使用上解析Re...
  • honghailiang888
  • honghailiang888
  • 2017年03月17日 12:58
  • 2852

Retrofit原理及调用流程分析

发表于3个月前(2014-07-30 10:27)   阅读(186) | 评论(0) 2人收藏此文章,我要收藏 赞0 摘要 Retrofit很有创意的一款开源网络框架,让用户自定义接口,并使用其...
  • mao520741111
  • mao520741111
  • 2014年11月07日 17:02
  • 11864

Android 网络框架之Retrofit2使用详解及从源码中解析原理

版权声明:本文为博主原创文章,未经博主允许不得转载。 目录(?)[+] 就目前来说Retrofit2使用的已相当的广泛,那么我们先来了解下两个问题: 1 ...
  • liner666
  • liner666
  • 2017年02月06日 10:18
  • 379

Android 网络框架之Retrofit2使用详解及从源码中解析原理

就目前来说Retrofit2使用的已相当的广泛,那么我们先来了解下两个问题:1 . 什么是Retrofit?Retrofit是针对于Android/Java的、基于okHttp的、一种轻量级且安全的、...
  • guiman
  • guiman
  • 2016年05月26日 16:32
  • 22427

登陆网络请求的Retrofit实现【新手】

介绍:Retrofit和OkHttp一样都是Square公司开发的,是针对Android网络请求的框架,Retrofit2底层就是基于OkHttp实现的,相当于对OkHttp做了一层封装。首先需要在g...
  • tiancaijunm
  • tiancaijunm
  • 2017年05月27日 19:12
  • 595
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:retrofit的实现原理(一)
举报原因:
原因补充:

(最多只允许输入30个字)