PS:看完了LGD的六场比赛...让人心酸...

学习内容:

1.Http请求的过程...

2.Volley的简单介绍...

 

1.Http请求...

  这里只是简单的说一下Http请求的过程...非常的简单...首先是发送Request..然后服务器在获取到Request请求后会对其进行相应的处理,然后以Response的形式进行返回,然后分配Response,即谁发送的请求,那么响应就分配给谁...

2.Volley简单介绍...

  这里只是先简单的说一下Volley,Volley框架是由Google发布的一款开源框架...这个框架主要是针对网络请求而包装生成的开源框架...主要功能是异步的网络请求和图片的加载,适用于Android这种请求频繁而每次请求数据量并不是很大的这一类网络请求...通过源码能够发现Volley有非常好的扩展性,更多的地方采用接口的设计...所以我们都可以自己重写内部的一些方法...总体的设计思路也是非常的明确的...

  客户端如果想通过网络连接来连接服务器,那么首先需要发送相关请求...每一个请求都需要被建立,那么建立请求的类就靠Request.java来实现...

  Request.java(源码解析)

  简单的说说Request.java,这是Volley的最核心的类,Request.java不仅仅封装了Request请求,还包括对服务器返回的Response的数据信息进行相应的处理..总之Request.java是一个最大的父类,内部封装了非常多的方法...其他的几个子类都是通过继承Request.java从而实现自己的功能...Request只是对外提供了一个接口,任何方式的请求只需要实现接口就能够实例化自己的请求对象,创建自己内部的方法..从而形成一种良好的扩展...

  凡是继承了Request.java必须要实现的一个方法...

abstract protected Response<T> parseNetworkResponse(NetworkResponse response);

  这个方法是对网络服务器响应的一个解析过程..也是最后由这个函数通过postResponse方法,将Response传递给ResponseDelivery从而对响应进行分发,不难理解,在每一个Request中实现这个方法,那么也就能够知道是谁发出的请求,这样在分发响应的时候也就不会产生错误...

  2.1 public void addMarker(String tag){}函数...

 public void addMarker(String tag) {
if (MarkerLog.ENABLED) {
mEventLog.add(tag, Thread.currentThread().getId());
} else if (mRequestBirthTime == 0) {
mRequestBirthTime = SystemClock.elapsedRealtime();
}
}

  addMarker函数,其实是就是一个标志,这个函数可以为每一个request添加相应事件标识符,这样我们就可以通过捕获标识符的方式从而对每一个request做进一步的操作.

  比如说一个网络请求从请求队列取出的标识:request.addMarker("network-queue-take");

        一个请求被取消的标识:request.addMarker("network-discard-cancelled");

  在Volley中很容易看到这些标识,他们的存在就是为了捕获每一个请求的发生状态,通过捕获这些状态,比如说一个请求已经完成,那么我们捕获到了请求完成之后,我们就需要将这次请求从请求队列当中移除,那么这个操作的执行就需要首先捕获到请求的状态,我们才能够采取下一步的操作...总之就是通过标识才能够清楚的了解请求到底执行到了何种状态...

  2.2 以下几个函数完成实体部分(Body)中验证参数的传递以及编码过程...

  2.2.1 public byte[] getPostBody() throws AuthFailureError{}

        public byte[] getBody() throws AuthFailureError{}

public byte[] getPostBody() throws AuthFailureError {
// Note: For compatibility with legacy clients of volley, this implementation must remain
// here instead of simply calling the getBody() function because this function must
// call getPostParams() and getPostParamsEncoding() since legacy clients would have
// overridden these two member functions for POST requests.
Map<String, String> postParams = getPostParams();
if (postParams != null && postParams.size() > 0) {
return encodeParameters(postParams, getPostParamsEncoding());
}
return null;
} public byte[] getBody() throws AuthFailureError {
Map<String, String> params = getParams();
if (params != null && params.size() > 0) {
return encodeParameters(params, getParamsEncoding());
}
return null;
}

   这两个函数想必大家看函数名称估计都能明白到底是怎么回事了,只不过这里有个小小的区别...第一个方法仅仅是对Post请求方式中Body实体部分的获取,而第二个是对Post或Put请求方式中Body实体部分的获取...

  我们知道网络请求时,信息是以数据报的形式进行传递的,数据报有头部(Headers)和实体(Body)部分...实体一般都是封装着想要发送的数据以及验证信息...因此想要获取Body中的实体数据就必须要通过某种方法来获取原生态的实体数据(Body)...获取了实体数据之后,就可以提交验证以及发送数据...那么上面两个函数就是用来解决这个问题的...

  我们可以从源码看到,二者分别调用getParams()和getPostParams()函数...

  2.2.2 protected Map<String,String> getPostParams() throws AuthFailureError{}

        protected Map<String,String> getParams() throws AuthFailureError{}

protected Map<String, String> getPostParams() throws AuthFailureError {
return getParams();
} protected Map<String, String> getParams() throws AuthFailureError {
return null;
}

  这两个方法就是获取数据报中Body用于验证或授权时传递的参数,通过源码我们可以看到,方法的返回值是空值,这也不难理解,如果客户端想要完成验证和授权,必须要由客户端发送验证数据,通过对客户端验证数据信息的抓取,接着应用程序重写上面的两个方法,客户端的验证数据信息被封装到这两个方法内,这样服务器就可以真正的获取到客户端提交的信息了..来张图片方便大家理解...

  这里还涉及到了一个参数的编码...通过调用encodeParamters()方法...

  2.2.3 private byte[] encodeParameters(Map<String,String>params,String paramsEncoding){}

  这个方法需要对传递过来的所有参数进行遍历...将参数转化成 postid=4868291&update=1 这样的形式...我们在访问网站的时候经常会在url看到这样类似的字串,那也就是传递的参数想必也就不难理解了...

private byte[] encodeParameters(Map<String, String> params, String paramsEncoding) {
StringBuilder encodedParams = new StringBuilder();
try {
for (Map.Entry<String, String> entry : params.entrySet()) {
encodedParams.append(URLEncoder.encode(entry.getKey(), paramsEncoding));
encodedParams.append('=');
encodedParams.append(URLEncoder.encode(entry.getValue(), paramsEncoding));
encodedParams.append('&');
}
return encodedParams.toString().getBytes(paramsEncoding);
} catch (UnsupportedEncodingException uee) {
throw new RuntimeException("Encoding not supported: " + paramsEncoding, uee);
}
}

  2.3 请求完成后需要执行的函数...

  2.3.1 void finish(final String tag){}

  当一个请求完成之后需要对做出一些操作,首先需要做的事情就是将请求队列中的这次请求进行移除操作,因为请求已经完成...这也不难理解,也就是下面源码第一个if执行的过程,他会再次调用RequestQueue中finish()函数,来移除这次请求,这个源码就先不介绍...等到后面介绍RequestQueue源码的时候再细细说一下...我们只需要知道现在它的功能就行了...也是这个函数的主要部分...而下面第二个if()函数,其实是为了转储这次请求中所有的日志文件,为了以后的调试...

 void finish(final String tag) {
if (mRequestQueue != null) {
mRequestQueue.finish(this);
}
if (MarkerLog.ENABLED) {
final long threadId = Thread.currentThread().getId();
if (Looper.myLooper() != Looper.getMainLooper()) {
// If we finish marking off of the main thread, we need to
// actually do it on the main thread to ensure correct ordering.
Handler mainThread = new Handler(Looper.getMainLooper());
mainThread.post(new Runnable() {
@Override
public void run() {
mEventLog.add(tag, threadId);
mEventLog.finish(this.toString());
}
});
return;
} mEventLog.add(tag, threadId);
mEventLog.finish(this.toString());
} else {
long requestTime = SystemClock.elapsedRealtime() - mRequestBirthTime;
if (requestTime >= SLOW_REQUEST_THRESHOLD_MS) {
VolleyLog.d("%d ms: %s", requestTime, this.toString());
}
}
}

  2.4 Request的构造函数...

  2.4.1 public Request(String url,Response.ErrorListener listener){}

        public Request(int method,String url,Response.ErrorListener listener){}

  构造函数分为两种,一个是直接通过url来执行请求,一个是通过指定提交方式,然后通过url来执行请求...

 public Request(String url, Response.ErrorListener listener) {
this(Method.DEPRECATED_GET_OR_POST, url, listener);
}
public Request(int method, String url, Response.ErrorListener listener) {
mMethod = method;
mUrl = url;
mErrorListener = listener;
setRetryPolicy(new DefaultRetryPolicy()); mDefaultTrafficStatsTag = TextUtils.isEmpty(url) ? 0: Uri.parse(url).getHost().hashCode();
}

  Request只是一个抽象接口,为外部暴露接口,从而让其他的类去实现,其中还有许多的方法,包括请求失败时的重试策略,以及请求缓存的一些定义...还有许多变量和方法,只是在Request中进行了封装,而真正去调用和实现这些方法则需要其他的类进行扩展...因此Request的源码只是做一些简单的介绍..介绍的也是其中非常重要的方法...其他的内容则在后续进行介绍...

 

     

 

 

 

Android 学习笔记之Volley开源框架解析(一)的更多相关文章

  1. Android 学习笔记之Volley开源框架解析(五)

    学习内容: 1.PoolingByteArrayOutputStream 2.ByteArrayPool 3.HttpStack 4.HurlStack 5.HttpHeaderParser   前面 ...

  2. Android 学习笔记之Volley开源框架解析(四)

    学习内容: 1.NetWorkDispatcher网络请求线程调度... 2.NetWork网络请求抽象类... 3.BasicNetWork网络请求抽象类的具体实现... 4.NetWorkResp ...

  3. Android 学习笔记之Volley开源框架解析(二)

    PS:Volley已经学完,可以安心的写一下博客总结一下了... 学习内容: 1.Request的完整封装... 2.RetryPolicy,DefaultRetryPolicy(请求重试策略源码解析 ...

  4. Android 学习笔记之Volley开源框架解析(三)

      学习内容: 1.CacheDispatcher缓存请求调度... 2.Cache缓存数据的保存... 3.DiskBasedCache基于磁盘的缓存类实现方式...   前面说到使用Volley发 ...

  5. Android 学习笔记之Volley(七)实现Json数据加载和解析...

    学习内容: 1.使用Volley实现异步加载Json数据...   Volley的第二大请求就是通过发送请求异步实现Json数据信息的加载,加载Json数据有两种方式,一种是通过获取Json对象,然后 ...

  6. Android(java)学习笔记214:开源框架的文件上传(只能使用Post)

    1.文件上传给服务器,服务器端必然要写代码进行支持,如下: 我们新建一个FileUpload.jsp的动态网页,同时我们上传文件只能使用post方式(不可能将上传数据拼凑在url路径下),上传数据Ap ...

  7. Android(java)学习笔记157:开源框架的文件上传(只能使用Post)

    1.文件上传给服务器,服务器端必然要写代码进行支持,如下: 我们新建一个FileUpload.jsp的动态网页,同时我们上传文件只能使用post方式(不可能将上传数据拼凑在url路径下),上传数据Ap ...

  8. Android(java)学习笔记213:开源框架post和get方式提交数据(qq登录案例)

    1.前面提到Http的get/post方式  . HttpClient方式,实际工作的时候不常用到,因为这些方式编写代码是很麻烦的 2.Android应用会经常使用http协议进行传输,网上会有很完善 ...

  9. Android(java)学习笔记156:开源框架post和get方式提交数据(qq登录案例)

    1. 前面提到Http的get/post方式  . HttpClient方式,实际工作的时候不常用到,因为这些方式编写代码是很麻烦的 2. Android应用会经常使用http协议进行传输,网上会有很 ...

随机推荐

  1. Asp.Net实现FORM认证的一些使用技巧(转)

    最近因为项目代码重构需要重新整理用户登录和权限控制的部分,现有的代码大体是参照了.NET的FORM认证,并结合了PORTAL KITS的登录控制,代码比较啰嗦,可维护性比较差.于是有了以下的几个需求( ...

  2. 深入理解Openstack自动化部署

    前言 说实话,看到自己在博客园的排名感到惭愧,因为自己最近两年没有持续地在博客园上写技术博客了,有人私下问我是不是荒废了?翻翻15年和16年的博客,真的是少的可怜.一方面的确由于岗位的变化,导致了工作 ...

  3. 小白学数据分析----->移动游戏的使用时长分析

    写下该文章,是因为之前看到了几款游戏一个典型的玩家刺激活动,在<多塔联盟>,<萌江湖>等多款游戏的设计中都有体现,如下图所示: 这个功能点的设计,今天在这里讲的更多的还是跟数据 ...

  4. 解决chi_sim.traineddata报read_params_file: parameter not found: allow_blob_division

    在使用语音库时候 遇到报错:allow_blob_division,例如使用chi_sim.traineddata;在chi_sim.traineddata(注意版本)文件目录下,使用命令行执行: c ...

  5. java微信开发API第一步 服务器接入

    I如何接入服务器,下面就为大家进行介绍 一.说明 * 本示例根据微信开发文档:http://mp.weixin.qq.com/wiki/home/index.html最新版(4/3/2016 5:34 ...

  6. Swift入门篇-基本类型(2)

    现在我也在学习Swift语言,常常去逛很多苹果社区和论坛,看到了圈子很多奇怪的现象,发现很多人都赶忙去翻译 Swift书籍 和 发布Swift的视频 .他们这种对新知识的探索精神我本人是很佩服的.但是 ...

  7. SNMP远程监控进程信息的OID

    最近有个项目需要用snmp远程监控进程信息.于是我查了一下资料. 一.资料 .1.3.6.1.2.1.25.4.2.1.1.iso.org.dod.internet.mgmt.mib-2.host.h ...

  8. hdu 1845

    一看题意就是二分匹配问题,建边是双向的,两个集合都是n个点 这题的图很特殊,每个点都要与三个点相连,在纸上画了六个点的图就感觉此图最大匹配肯定是六,除以2就是原图的匹配了,就感觉这样的图肯定会达到满匹 ...

  9. log4j总结

    log4j介绍 Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台.文件.GUI组件.甚至是套接口服务 器.NT的事件记录器.UNIX Sysl ...

  10. session和jsessionid有什么关系

    首先,并不是说你一打开一个页面就会产生一个session. 所谓session你可以这样理解:当你与服务端进行会话时,比如说登陆成功后,服务端会为你开壁一块内存区间,用以存放你这次会话的一些内容,比如 ...