转载请注明出处,本文来自【 Mr.Simple的博客 】。
我正在参加博客之星,点击这里投我一票吧,谢谢~
前言
在教你写Android网络框架之基本架构一文中我们已经介绍了SimpleNet网络框架的基本结构,今天我们就开始从代码的角度来开始切入该网络框架的实现,在剖析的同时我们会分析设计思路,以及为什么要这样做,这样做的好处是什么。这样我们不仅学到了如何实现网络框架,也会学到设计一个通用的框架应该有哪些考虑,这就扩展到框架设计的范畴,通过这个简单的实例希望能给新人一些帮助。当然这只是一家之言,大家都可以有自己的实现思路。
正如你所看到的,这系列博客是为新人准备的,如果你是高手,请忽略。
在框架开发当中,很重要的一点就是抽象。也就是面向对象中重要的一条原则: 依赖倒置原则,简单来说就是要依赖抽象,而不依赖具体。这样就使得我们的框架具有可扩展性,同时也满足了开闭原则,即对扩展开放,对修改关闭。针对于我们的网络框架来说,最重要的抽象就是Reqeust类、Response类,因此今天我们就从两个类开始切入。最后我们再引入网络框架中的请求队列(RequestQueue),这是SimpleNet中的中枢神经,所有的请求都需要放到该队列,然后等待着被执行。请求队列就像工厂中的流水线一样,而网络请求就像流水线上的待加工的产品。执行网络请求的对象就类似工厂中的工人,在自己的岗位上等待流水线上传递过来的产品,然后对其加工,加工完就将产品放到其他的位置。它们角色对应关系参考图1,如对SimpleNet的一些角色不太清楚可参考教你写Android网络框架之基本架构一文。
图1
Request类
既然网络框架,那么我们先从网络请求类开始。前文已经说过,既然是框架,那么就需要可扩展性。因此注定了Request是抽象,而不是具体。而对于网络请求来说,用户得到的请求结果格式是不确定,比如有的服务器返回的是json,有的返回的是xml,有的直接是字符串。但是对于Http Response来说,它的返回数据类型都是Stream,也就是我们得到的原始数据都是二进制的流。所以在Request基类中我们必须预留方法来解析Response返回的具体类型,虽然返回的类型不同,但是他们的处理逻辑是一样的,因此我们可把Request作为泛型类,它的泛型类型就是它的返回数据类型,比如Request<String>,那么它的返回数据类型就是String类型的。另外还有请求的优先级、可取消等,我们这里先给出核心代码,然后再继续分析。
/** * 网络请求类. 注意GET和DELETE不能传递请求参数,因为其请求的性质所致,用户可以将参数构建到url后传递进来到Request中. * * @author mrsimple * @param <T> T为请求返回的数据类型 */public abstract class Request<T> implements Comparable<Request<T>> { /** * http请求方法枚举,这里我们只有GET, POST, PUT, DELETE四种 * * @author mrsimple */ public static enum HttpMethod { GET("GET"), POST("POST"), PUT("PUT"), DELETE("DELETE"); /** http request type */ private String mHttpMethod = ""; private HttpMethod(String method) { mHttpMethod = method; } @Override public String toString() { return mHttpMethod; } } /** * 优先级枚举 * * @author mrsimple */ public static enum Priority { LOW, NORMAL, HIGN, IMMEDIATE } /** * Default encoding for POST or PUT parameters. See * {
@link #getParamsEncoding()}. */ private static final String DEFAULT_PARAMS_ENCODING = "UTF-8"; /** * 请求序列号 */ protected int mSerialNum = 0; /** * 优先级默认设置为Normal */ protected Priority mPriority = Priority.NORMAL; /** * 是否取消该请求 */ protected boolean isCancel = false; /** 该请求是否应该缓存 */ private boolean mShouldCache = true; /** * 请求Listener */ protected RequestListener<T&g