在分析其它框架之前,先做一个简易的网络请求框架。这里的结构和 Volley 一致,主要分为 4 部分,如图:

OkHttp 是一个高效的 HTTP 库,它实现了几乎和java.net.HttpURLConnection一样的API:
Http2.0 的支持,共享同一个Socket来处理同一个服务器的所有请求 如果 Http2.0 不可用,通过连接池来减少请求延迟 支持传输 GZip 来减少数据流量 缓存 Response,避免相同的请求框架图:
主要是通过 Diapatcher 不断从RequestQueue中取出请求(Call),根据是否已缓存调用 Cache 或 Network 这两类数据获取接口之一,从内存缓存或是服务器取得请求的数据。该引擎有同步和异步请求,同步请求通过 Call.execute() 直接返 回当前的 Response ,而异步请求会把当前的请求Call.enqueue添加(AsyncCall)到请求队列中,并通过回调(Callback) 的方式来获取最后结果。
Retrofit 是一个类型安全的 REST 客户端,在 Retrofit2 依赖了 OkHttp。在使用上拥有如下优点:
可以利用接口,方法和注解参数(parameter annotations)来声明式定义一个请求应该如何被创建。 支持序列化机制(JSON/xml 协议)在一个类型中的同步和异步请求Retrofit2 发布会链接:https://realm.io/cn/news/droidcon-jake-wharton-simple-http-retrofit-2
Volley 是 Google 在 2013 年推出的 Android 异步网络请求框架和图片加载框架。
Volley 的主要特点:
扩展性强。Volley 中大多是基于接口的设计,可配置性强。 一定程度符合 Http 规范,包括返回 ResponseCode(2xx、3xx、4xx、5xx)的处理,请求头的处理,缓存机制的支持等。并支持重试及优先级定义。 默认 Android2.3 及以上基于 HttpURLConnection,2.3 以下基于 HttpClient 实现,这两者的区别及优劣在4.2.1 Volley中具体介绍。 提供简便的图片加载工具。总体设计图

通过两种Dispatch Thread不断从RequestQueue中取出请求,根据是否已缓存调用Cache或Network这两类数据获取接口之一,从内存缓存或是服务器取得请求的数据,然后交由ResponseDelivery去做结果分发及回调处理。
Apache HttpClient 已不被推荐使用,并在 6.0 上被删除。Google 推荐在 Android 上使用 HttpUrlConnection。DefaultHttpClient和它的兄弟AndroidHttpClient都是HttpClient具体的实现类,它们都拥有众多的API,而且实现比较稳定,bug数量也很少。但同时也由于HttpClient的API数量过多,使得我们很难在不破坏兼容性的情况下对它进行升级和扩展。虽然高效稳定,但是维护成本高昂,故android 开发团队不愿意在维护该库而是转投更为轻便的 HttpUrlConnection。
HttpURLConnection 是一种多用途、轻量极的 HTTP 客户端,使用它来进行 HTTP 操作可以适用于大多数的应用程序。虽然 HttpURLConnection 的 API 提供的比较简单,但是同时这也使得我们可以更加容易地去使用和扩展它。在 Android 2.2 版本之前,HttpURLConnection 一直存在着一些令人厌烦的 BUG,因此 Volley 框架在 2.2 之前使用的是 HttpClient。
OKHttp 是一款高效的 HTTP 客户端,支持 SPDY(或HTTP)、连接池、GZIP 和 HTTP 缓存,使用 Okio 来大大简化数据的访问与存储。同时处理了很多网络疑难杂症,会从很多常用的连接问题中自动恢复,处理了代理服务器问题和SSL握手失败问题。Android4.4 开始 HttpURLConnection 的底层实现采用的是 OkHttp。
官方文档:http://square.github.io/retrofit/
从 GitHub 的 star 排名来看,Retrofit 数量是最多的,其次是 Okhttp,并且 Retrofit 的网络请求框架也是依赖 OKhttp 的,在网络性能上相当不错;又因为 Retrofit 通过接口注解的方式定义 Http Api,可以很方便的管理和调用;另外 GitHub 上还有一些基于 Okhttp 框架拓展的新框架(如 OkGo),使该框架也具有较强的拓展性。最终决定采用 Retrofit 作为现阶段我们应用网络请求的主流框架。
请求的 Http 接口需要定义在 Java 接口中,如下:
public interface GitHubService { @GET("users/{user}/repos") Call<List<Repo>> listRepos(@Path("user") String user);}用 Retrofit 创建一个实现了 GitHubService 接口的对象:
Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.github.com/") .build();GitHubService service = retrofit.create(GitHubService.class);最后调用接口中的方法来请求服务器,并返回一个 Call 对象:
Call<List<Repo>> repos = service.listRepos("octocat");@Path 在替换 Http 接口中的路径时,用 @path 属性。如下:
@GET("group/{id}/users")Call<List<User>> groupList(@Path("id") int groupId);@Query 在替换 Http 接口中的参数时,用 @Query 属性。如下:
@GET("group/123456/users")Call<List<User>> groupList(@Query("sort") String sort);等同于: group/123456/users?sort=name
@QueryMap 在请求参数过多时,可以通过键值对的形式,如下:
@GET("group/123456/users")Call<List<User>> groupList(@QueryMap Map<String, String> options);@Body 可以把一个对象作为请求内容传递,用法如下:
@POST("users/new")Call<User> createUser(@Body User user);@Field 在方法的参数中添加 @Field 注解,并在方法上加上 @FormUrlEncoded 注解,代码如下:
@FormUrlEncoded@POST("user/edit")Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);@Part 多部分请求在方法上添加 @Multipart,并在参数前加入 @Part 属性,代码如下:
@Multipart@PUT("user/photo")Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);@Headers 请求头信息通过 @Headers 注释设置,代码如下:
@Headers("Cache-Control: max-age=640000")@GET("widget/list")Call<List<Widget>> widgetList();// 多条参数@Headers({ "Accept: application/vnd.github.v3.full+json", "User-Agent: Retrofit-Sample-App"})@GET("users/{username}")Call<User> getUser(@Path("username") String username);另外,可以通过注解动态的使用,如下:
@GET("user")Call<User> getUser(@Header("Authorization") String authorization)原文链接:http://www.ionesmile.com/android/network-framework
参考网站:
Okhttp 源码分析: http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0326/2643.htmlVolley 源码解析: http://a.codekk.com/detail/Android/grumoon/Volley%20%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90
教你写Android网络框架之基本架构 http://blog.csdn.net/bboyfeiyu/article/details/42740443/
新闻热点
疑难解答