zoukankan      html  css  js  c++  java
  • Android.Volley的解读:request

    这文章是用来记录自己最近使用volley的StringRequest的一些心得,以及volley关于request的代码深读。

    从网络上可以知道,volley适合数据量不大但是通信频繁的场景。volley提供的便利功能有如下这些:

    • JSON,图像等的异步下载;
    • 网络请求的排序(scheduling)
    • 网络请求的优先级处理
    • 缓存
    • 多级别取消请求
    • 和Activity和生命周期的联动(Activity结束时同时取消所有网络请求)

    从一些网络前辈和自己使用的情况来说,volley的图片处理并不是最佳,我选择了Picasso,所以我只用到了request,以及和Activity生命周期的联动两个特性。

    之前写了一篇volley的初接触,主要是Volley.newRequestQueue(getApplicationContext());这句代码的解读。

    以下开始解读StringRequest。

    网络上的前辈都把StringRequest请求当做自定义请求,和JsonObjecy JsonArray 区别开,我也不清楚为什么要这样区别,暂且没用过volley的json请求,但是看过介绍,感觉所有的request都差不多。

    使用情景,利用StringRequest请求解析一段xml数据。

    StringRequest request = new StringRequest(
        Request.Method.GET,
        Contants.HTTP_SERVER + Contants.HTTP_TABS,
        new Response.Listener<String>(){
        @Override
        public void onResponse(String response){
          //这里处理请求返回的response
          ... ...
        }
      }, new Response.ErrorListener(){
        @Override
        public void onErrorResponse(VolleyError error){
          //这里处理请求失败的工作
          LogUtils.d(TAG,error.toString());
        }
      }
    );

    还是一句代码,所有用到的参数都出现了,现在到StringRequest看看情况

    public class StringRequest extends Request<String> {
        private final Listener<String> mListener;
        
        public StringRequest(int method, String url, Listener<String> listener,
                ErrorListener errorListener) {
            super(method, url, errorListener);    //这里是调用super 不是 this
            mListener = listener;
        }
    
        public StringRequest(String url, Listener<String> listener, ErrorListener errorListener) {
            this(Method.GET, url, listener, errorListener);
        }
    
        @Override
        protected void deliverResponse(String response) {
            mListener.onResponse(response);    //设置我们的listener
        }
    
        @Override
        protected Response<String> parseNetworkResponse(NetworkResponse response) {
        //字面意思 解析网络响应 String parsed; try { parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers)); } catch (UnsupportedEncodingException e) { parsed = new String(response.data); } return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response)); }

    StringRequest类的代码不多,但都是重要的组成部分。

    这里记录自己当初的两个惑点super(method, url, errorListener) 和 parseNetworkResponse & mListener.onResponse(response)的区别。

    首先是super(method, url, errorListener) :StringRequest继承Request<String>,跳转到Request<String>中

        public Request(int method, String url, Response.ErrorListener listener) {
            mMethod = method;
            mUrl = url;
            mErrorListener = listener;
            setRetryPolicy(new DefaultRetryPolicy());
    
            mDefaultTrafficStatsTag = findDefaultTrafficStatsTag(url);
        }
    

    Request中保存了提交方式,连接的url,错误监听接口,并设置了重试策略,而且从url中找到通信状态标志(有什么用?)

    设置重试策略感觉很好理解,看看DefaultRetryPolicy类就知道七八分了,作用大概就是设置url连接的失败重试的一些属性(我自己脑补的-_-!!!)

        public DefaultRetryPolicy() {
            this(DEFAULT_TIMEOUT_MS, DEFAULT_MAX_RETRIES, DEFAULT_BACKOFF_MULT);
        }
    
        ...
        /**
         * Constructs a new retry policy.
         * @param initialTimeoutMs The initial timeout for the policy.
         * @param maxNumRetries The maximum number of retries.
         * @param backoffMultiplier Backoff multiplier for the policy.
         */
        public DefaultRetryPolicy(int initialTimeoutMs, int maxNumRetries, float backoffMultiplier) {
            mCurrentTimeoutMs = initialTimeoutMs;
            mMaxNumRetries = maxNumRetries;
            mBackoffMultiplier = backoffMultiplier;
        }
    

    剩下的mDefaultTrafficStatsTag = findDefaultTrafficStatsTag(url);函数的javadoc里解释返回The hashcode of the URL's host component, or 0 if there is none,这下就不太好脑补了,还是先看看函数的实现。

        private static int findDefaultTrafficStatsTag(String url) {
            if (!TextUtils.isEmpty(url)) {
                Uri uri = Uri.parse(url);
                if (uri != null) {
                    String host = uri.getHost();
                    if (host != null) {
                        return host.hashCode();
                    }
                } 
            }
            return 0;
        }
    

    看到出奇简单的代码,我联想到了volley的缓存机制,听说是简单的判断url是否相同,难道就是这个??是不是这个也不重要了,反正StringRequest的初始化属性如上。

    剩下就是deliverResponse和parseNetworkResponse,然后从网络上找到了一篇说得比较清楚得文章

    http://www.apihome.cn/view-detail-70213.html

    我用自己的白话文归纳一下:parseNetworkResponse是用于特定类型(String、Json、JsonArray、Image)请求的解析,把服务端返回的数据解析成指定类型,然后系统回调deliverResponse派发相应的实例当中。不太明白可以看看以上类型对应的Request,里面都用parseNetworkResponse把NetworkResponse转变成相应类型。

    Note:在我没写这篇文章前,我都是直接在初始化StringRequest请求的时候,我都没有重写parseNetworkResponse,直接拿到服务端的原始string,然后在Response.listener中的onResponse中进行处理,感觉不太native。感谢网络上的前辈,感谢自己。

    补充一张超大图。是我自己画的volley工作视图,请下载放大查看。

  • 相关阅读:
    TF-IDF
    线性回归梳理
    snappy 在linux安装及使用
    Hbase 写入机制详解与MVCC机制
    phoenix二级索引源码阅读
    利用SET工具制造钓鱼网站
    jQuery框架漏洞全总结及开发建议
    DDE注入(CSV)漏洞原理及实战案例全汇总
    burp插件大全 漏洞扫描 waf绕过 sql XSS 命令注入 fuzzer
    点击劫持(ClickJacking)漏洞挖掘及实战案例全汇总
  • 原文地址:https://www.cnblogs.com/zzrblog/p/4208905.html
Copyright © 2011-2022 走看看