程序员人生 网站导航

[置顶] 58. SaveVolley

栏目:综合技术时间:2017-01-13 10:55:27

SaveVolley


Save volley from anything, By Agera to save. Thus, derived the AgeraVolley . (。>﹏<。)


gson: 2.7

fastjson: 1.1.52.android

agera: 1.1.0

okhttp3: 3.3.1



savevolley-okhttp3-agera-gson || savevolley-okhttp3-agera-fastjson


savevolley-okhttp3-agera-gson gradle

dependencies {
    compile 'com.google.code.gson:gson:2.7'
    compile 'com.squareup.okhttp3:okhttp:3.3.1'
    compile 'com.google.android.agera:agera:1.1.0'

    // for okhttp3
    compile 'com.camnter.savevolley:okhttp3:1.6.6'
    // for gson
    compile 'com.camnter.savevolley:savevolley-okhttp3-agera-gson:1.6.6'
}

可使用 SaveVolley Flowagera Flow

    SaveVolley saveVolley = SaveVolleys
        .<GankData>request(TEST_URL)
        .method(Method.GET)
        .parseStyle(GSON)
        .classOf(GankData.class)
        .createRequest()
        .context(this)
        .compile();

    final Repository<GankResultData> repository = Repositories.repositoryWithInitialValue(
        INITIAL_VALUE)
        .observe(saveVolley.getReservoir())
        .onUpdatesPerLoop()
        .goTo(executor)
        .attemptGetFrom(saveVolley.getReservoir())
        .orSkip()
        .thenAttemptTransform(new Function<Object, Result<GankResultData>>() {
            /**
             * Returns the result of applying this function to {@code input}.
             */
            @NonNull @Override public Result<GankResultData> apply(@NonNull Object input) {
                if (input instanceof GankData) {
                    return Result.success(((GankData) input).results.get(0));
                } else if (input instanceof VolleyError) {
                    return Result.failure((VolleyError) input);
                }
                return Result.failure();
            }
        })
        .orSkip()
        .compile();

    repository.addUpdatable(new Updatable() {
        @Override public void update() {
            getContentText.setText(repository.get().toString());
        }
    });


savevolley-okhttp3-agera-fastjson gradle

dependencies {
    compile 'com.alibaba:fastjson:1.1.52.android'
    compile 'com.squareup.okhttp3:okhttp:3.3.1'
    compile 'com.google.android.agera:agera:1.1.0'

    // for okhttp3
    compile 'com.camnter.savevolley:okhttp3:1.6.6'
    // for fastjson
    compile 'com.camnter.savevolley:savevolley-okhttp3-agera-fastjson:1.6.6'
}
    SaveVolley saveVolley = SaveVolleys
        .<GankData>request(TEST_URL)
        .method(Method.GET)
        .parseStyle(FASTJSON)
        .classOf(GankData.class)
        .createRequest()
        .context(this)
        .compile();

    final Repository<GankResultData> repository = Repositories
        .repositoryWithInitialValue(INITIAL_VALUE)
        .observe(saveVolley.getReservoir())
        .onUpdatesPerLoop()
        .goTo(executor)
        .attemptGetFrom(saveVolley.getReservoir())
        .orSkip()
        .thenAttemptTransform(new Function<Object, Result<GankResultData>>() {
            /**
             * Returns the result of applying this function to {@code input}.
             */
            @NonNull @Override public Result<GankResultData> apply(@NonNull Object input) {
                if (input instanceof GankData) {
                    return Result.success(((GankData) input).results.get(0));
                } else if (input instanceof VolleyError) {
                    return Result.failure((VolleyError) input);
                }
                return Result.failure();
            }
        })
        .orSkip()
        .compile();

    repository.addUpdatable(new Updatable() {
        @Override public void update() {
            getContentText.setText(repository.get().toString());
        }
    });



savevolley-hurl-agera-gson || savevolley-hurl-agera-fastjson

可使用 SaveVolley Flowagera Flow


savevolley-hurl-agera-gson gradle

dependencies {
    compile 'com.google.code.gson:gson:2.7'
    compile 'com.google.android.agera:agera:1.1.0'

    // for hurl
    compile 'com.camnter.savevolley:hurl:1.6.6'
    // for gson
    compile 'com.camnter.savevolley:savevolley-hurl-agera-gson:1.6.6'
}
    SaveVolley saveVolley = SaveVolleys
        .<GankData>request(TEST_URL)
        .method(Method.GET)
        .parseStyle(GSON)
        .classOf(GankData.class)
        .createRequest()
        .context(this)
        .compile();

    final Repository<GankResultData> repository = Repositories.repositoryWithInitialValue(
        INITIAL_VALUE)
        .observe(saveVolley.getReservoir())
        .onUpdatesPerLoop()
        .goTo(executor)
        .attemptGetFrom(saveVolley.getReservoir())
        .orSkip()
        .thenAttemptTransform(new Function<Object, Result<GankResultData>>() {
            /**
             * Returns the result of applying this function to {@code input}.
             */
            @NonNull @Override public Result<GankResultData> apply(@NonNull Object input) {
                if (input instanceof GankData) {
                    return Result.success(((GankData) input).results.get(0));
                } else if (input instanceof VolleyError) {
                    return Result.failure((VolleyError) input);
                }
                return Result.failure();
            }
        })
        .orSkip()
        .compile();

    repository.addUpdatable(new Updatable() {
        @Override public void update() {
            getContentText.setText(repository.get().toString());
        }
    });


savevolley-hurl-agera-fastjson gradle

dependencies {
    compile 'com.alibaba:fastjson:1.1.52.android'
    compile 'com.google.android.agera:agera:1.1.0'

    // for hurl
    compile 'com.camnter.savevolley:hurl:1.6.6'
    // for fastjson
    compile 'com.camnter.savevolley:savevolley-hurl-agera-fastjson:1.6.6'
}
    SaveVolley saveVolley = SaveVolleys
        .<GankData>request(TEST_URL)
        .method(Method.GET)
        .parseStyle(FASTJSON)
        .classOf(GankData.class)
        .createRequest()
        .context(this)
        .compile();

    final Repository<GankResultData> repository = Repositories
        .repositoryWithInitialValue(INITIAL_VALUE)
        .observe(saveVolley.getReservoir())
        .onUpdatesPerLoop()
        .goTo(executor)
        .attemptGetFrom(saveVolley.getReservoir())
        .orSkip()
        .thenAttemptTransform(new Function<Object, Result<GankResultData>>() {
            /**
             * Returns the result of applying this function to {@code input}.
             */
            @NonNull @Override public Result<GankResultData> apply(@NonNull Object input) {
                if (input instanceof GankData) {
                    return Result.success(((GankData) input).results.get(0));
                } else if (input instanceof VolleyError) {
                    return Result.failure((VolleyError) input);
                }
                return Result.failure();
            }
        })
        .orSkip()
        .compile();

    repository.addUpdatable(new Updatable() {
        @Override public void update() {
            getContentText.setText(repository.get().toString());
        }
    });



savevolley-okhttp3-gson || savevolley-okhttp3-fastjson


savevolley-okhttp3-gson gradle

dependencies {
    compile 'com.google.code.gson:gson:2.7'
    compile 'com.squareup.okhttp3:okhttp:3.3.1'

    // for okhttp3
    compile 'com.camnter.savevolley:okhttp3:1.6.6'
    // for gson
    compile 'com.camnter.savevolley:savevolley-okhttp3-gson:1.6.6'
}

可使用 OkHttp3GsonRequest

    RequestQueue queue = Volley.newRequestQueue(this);
    queue.add(new OkHttp3GsonRequest<GankData>(TEST_URL,
        GankData.class) {
        /**
         * Called when a response is received.
         */
        @Override public void onResponse(GankData response) {
            getContentText.setText(response.toString());
        }


        /**
         * Callback method that an error has been occurred with the
         * provided error code and optional user-readable message.
         */
        @Override public void onErrorResponse(VolleyError error) {
            Toast.makeText(Okhttp3GsonActivity.this,
                error != null && error.getMessage() != null
                ? error.getMessage()
                : "No error message", Toast.LENGTH_LONG)
                .show();
            Log.d("GsonRequest", error != null && error.getMessage() != null
                                 ? error.getMessage()
                                 : "No error message");
        }
    });


savevolley-okhttp3-fastjson gradle

dependencies {
    compile 'com.alibaba:fastjson:1.1.52.android'

    // for okhttp3
    compile 'com.camnter.savevolley:okhttp3:1.6.6'
    // for fastjson
    compile 'com.camnter.savevolley:savevolley-okhttp3-fastjson:1.6.6'
}

可使用 Okhttp3FastjsonRequest

    RequestQueue queue = Volley.newRequestQueue(this);
    queue.add(new OkHttp3FastjsonRequest<GankData>(TEST_URL, GankData.class) {
        /**
         * Called when a response is received.
         */
        @Override public void onResponse(GankData response) {
            getContentText.setText(response.toString());
        }


        /**
         * Callback method that an error has been occurred with the
         * provided error code and optional user-readable message.
         */
        @Override public void onErrorResponse(VolleyError error) {
            Toast.makeText(Okhttp3FastjsonActivity.this,
                error != null && error.getMessage() != null
                ? error.getMessage()
                : "No error message", Toast.LENGTH_LONG)
                .show();
            Log.d("GsonRequest", error != null && error.getMessage() != null
                                 ? error.getMessage()
                                 : "No error message");
        }
    });



savevolley-hurl-gson || savevolley-hurl-fastjson


savevolley-hurl-gson gradle

dependencies {
    compile 'com.google.code.gson:gson:2.7'

    // for hurl
    compile 'com.camnter.savevolley:hurl:1.6.6'
    // for gson
    compile 'com.camnter.savevolley:savevolley-hurl-gson:1.6.6'
}

可使用 HurlGsonRequest

    RequestQueue queue = Volley.newRequestQueue(this);
    queue.add(new HurlGsonRequest<GankData>(TEST_URL,
        GankData.class) {
        /**
         * Called when a response is received.
         */
        @Override public void onResponse(GankData response) {
            getContentText.setText(response.toString());
        }


        /**
         * Callback method that an error has been occurred with the
         * provided error code and optional user-readable message.
         */
        @Override public void onErrorResponse(VolleyError error) {
            Toast.makeText(HurlGsonActivity.this,
                error != null && error.getMessage() != null
                ? error.getMessage()
                : "No error message", Toast.LENGTH_LONG)
                .show();
            Log.d("GsonRequest", error != null && error.getMessage() != null
                                 ? error.getMessage()
                                 : "No error message");
        }
    });


savevolley-hurl-fastjson gradle

dependencies {
    compile 'com.alibaba:fastjson:1.1.52.android'

    // for hurl
    compile 'com.camnter.savevolley:hurl:1.6.6'
    // for fastjson
    compile 'com.camnter.savevolley:savevolley-hurl-fastjson:1.6.6'
}

可使用 HurlFastjsonRequest

    RequestQueue queue = Volley.newRequestQueue(this);
    queue.add(new HurlFastjsonRequest<GankData>(TEST_URL, GankData.class) {
        /**
         * Called when a response is received.
         */
        @Override public void onResponse(GankData response) {
            getContentText.setText(response.toString());
        }


        /**
         * Callback method that an error has been occurred with the
         * provided error code and optional user-readable message.
         */
        @Override public void onErrorResponse(VolleyError error) {
            Toast.makeText(HurlFastjsonActivity.this,
                error != null && error.getMessage() != null
                ? error.getMessage()
                : "No error message", Toast.LENGTH_LONG)
                .show();
            Log.d("GsonRequest", error != null && error.getMessage() != null
                                 ? error.getMessage()
                                 : "No error message");
        }
    });



savevolley-okhttp3


gradle

dependencies {
    // for okhttp3
    compile 'com.camnter.savevolley:okhttp3:1.6.6'
}

savevolley-okhttp3

将 原版的 google/volley 中 网络实现层 的 Apache HttpClient原生的 HttpUrlConnection 都移除。
换成 square/okhttp3 作为实现网络要求。



savevolley-hurl


gradle

dependencies {
    // for hurl
    compile 'com.camnter.savevolley:hurl:1.6.6'
}

API >= 9

savevolley-hurl

移除 原版 google/volley 中的,所有相干与 HttpClient 的逻辑,全版本的网络通讯接入到 HttpUrlConnection 内。



savevolley-network-core

savevolley-network-core

由于,网络底层实现( 网络要求实现 )可以通过不同框架( okhttp、HttpUrlConnection、Apache HttpClient … )去实现。
所以,只是拿到 不同框架的响应结果
但是 Volley 的缓存层是 通用的,所以需要定义1套 通用的 HTTP Response API,然后将 不同框架的响应结果 转换为
通用的 HTTP Response API

这个模块还需要与 savevolley-network-adapter 的子模块( savevolley-network-okhttp3-adapter, savevolley-network-hurl-adapter )1起协作。



savevolley-network-adapter

savevolley-network-adapter

目的是为了定义1些接口: 不同框架的响应结果 >> 通用的 HTTP Response API
子模块有: savevolley-network-okhttp3-adapter, savevolley-network-hurl-adapter 。



savevolley-network-okhttp3-adapter

savevolley-network-okhttp3-adapter

savevolley-network-adapter 的子模块,square/okhttp Response >> 通用的 HTTP Response API



savevolley-network-hurl-adapter

savevolley-network-hurl-adapter

savevolley-network-adapter 的子模块,HttpConnection >> 通用的 HTTP Response API



extensions / savevolley-hurl-agera-core

savevolley-hurl-agera-core

作用: 提供1些 hurlagera 协作需要的基础类。



extensions / savevolley-okhttp3-agera-core

savevolley-okhttp3-agera-core

作用: 提供1些 okhttp3agera 协作需要的基础类。



extensions / agera-gson / savevolley-okhttp3-agera-gson

savevolley-okhttp3-agera-gson

作用: agera >> savevolley-okhttp3 << gson , 为 savevolley-okhttp3 桥接了 ageragson



extensions / agera-gson / savevolley-hurl-agera-gson

savevolley-hurl-agera-gson

作用: agera >> savevolley-hurl << gson , 为 savevolley-hurl 桥接了 ageragson



extensions / agera-fastjson / savevolley-okhttp3-agera-fastjson

savevolley-okhttp3-agera-fastjson

作用: agera >> savevolley-okhttp3 << fastjson , 为 savevolley-okhttp3 桥接了 agerafastjson



extensions / agera-fastjson / savevolley-hurl-agera-fastjson

savevolley-hurl-agera-fastjson

作用: agera >> savevolley-hurl << fastjson , 为 savevolley-hurl 桥接了 agerafastjson



extensions / fastjson / savevolley-hurl-fastjson

savevolley-hurl-fastjson

作用: fastjson >> savevolley-hurl



extensions / fastjson / savevolley-okhttp3-fastjson

savevolley-okhttp3-fastjson

作用: fastjson >> savevolley-okhttp3



extensions / gson / savevolley-hurl-gson

savevolley-hurl-gson

作用: gson >> savevolley-hurl



extensions / gson / savevolley-okhttp3-gson

savevolley-okhttp3-gson

作用: gson >> savevolley-okhttp3



square-okhttp3

square/okhttp Version: 3.3.1



google-agera

google/agera Version: 1.1.0-beta2



volley-comments

volley-comments

原版的 google/volley,全部代码加上了注释。


入口

Volley:Volley 框架使用的入口,用于创建1个 RequestQueue。

  • 1. RequestQueue queue = Volley.newRequestQueue(this)

  • 2. queue.add(request)

RequestQueueRequestQueue 被定义为 要求队列。用于操作 缓存要求履行线程( CacheDispatcher )和 网络要求履行线程( NetworkDispatcher )。默许的情况下:

  • 1. 启动 1 个 缓存要求履行线程( CacheDispatcher )。

  • 2. 根据 DEFAULT_NETWORK_THREAD_POOL_SIZE 的值,启动 4 个 网络要求履行线程( NetworkDispatcher )。

  • 3. 这些线程同享 缓存要求队列 ( mCacheQueue )和 网络要求队列( mNetworkQueue ),当 RequestQueue 进行 要求的 添加、结束时,都会进入同步操作,保证线程安全。所以,RequestQueue 进行 要求的 添加、结束。是直接影响 CacheDispatcher 和 NetworkDispatcher 的履行


核心 异步

NetworkDispatcher:是用于处理 Volley 中的网络要求 的 网络线程,会将 网络 Request 队列的 Request 逐一抽出,然落后行网络要求:

  • 1. 成功,拿到数据进行解析,然后将 Response 进行硬盘缓存,缓存成 Cache.Entry 的情势,最后 传递 RequestResponse 数据。

  • 2. 失败,失败的话,1般会抛出异常,然落后行 记录要求时长传递毛病( VolleyError )

CacheDispatcher:是用于处理 Volley 中的缓存数据 的 缓存线程

  • 1.1. 检查缓存。从 缓存 Request 队列中取出 缓存 Request,然后 根据 缓存 Request CacheKey 去硬盘缓存( DiskBasedCache )映照过来的内存缓存中寻觅 是不是存在 EntryResponse )。

  • 1.2. 存在的话,通过 DefaultRetryPolicy 回传相干数据。

  • 1.3. 存在但缓存需要刷新的话,放入 网络 Request 队列 内,会在 NetworkDispatcher 的循环体中被用来 重新要求

  • 1.4. 不存在的话,将该 Request,放入 网络 Request 队列 内,会在 NetworkDispatcher 的循环体中被用来 重新要求

  • 2. CacheDispatcher 只做缓存相干的操作,不做网络的操作。所以 CacheDispatcher只触及到 缓存 Response 的增删改查 和 查询成功后的数据分发( 传递 )


网络要求 使用层

Network:在 Volley 中,是处理 网络要求 的表层使用接口。只有1个方法:performRequest(...) 履行要求,

BasicNetworkBasicNetwork 是 目前 Volley 内,Network 接口的唯1实现类,在 Volley 内,处理了 网络要求 的表层使用接口。实现了 performRequest(...) 方法的具体功能,performRequest(...) 要做的事情是

  • 1. 调用 HttpStack 接口的实现类 ( HurlStack, HttpClientStack ) 去履行网络要求实现,会拿到1个 Apache HttpResponse

  • 2. 然后,将 Apache HttpResponse -> Volley NetworkResponse 进行转化,并返回。


网络要求 实现层

HttpStackHttpStack 是 Volley 内 履行 网络要求 的 底层实现接口。实现类有:

  • 1. HttpClientStack:基于 org.apache.http 的网络要求实现。负责 系统版本 2.3 以下 的 网络要求实现。

  • 2. HurlStack:基于 HttpURLConnection 的网络要求实现。负责 系统版本 2.3 以上 的 网络要求实现。

HttpClientStackHttpClientStack 实现了 HttpStack 接口。封装了基于 org.apache.http.HttpClient 提供的网络实现( performRequest(...) ),处理了 2.3 版本以下的 各种网络要求( GET、POST、DEL … )的实现

HurlStackHurlStack 实现了 HttpStack 接口。封装了基于 javax.net.ssl.HttpsURLConnection 提供的网络实现( performRequest(...) ),处理了 2.3 版本以上的 各种网络要求( GET、POST、DEL … )的实现


要求( Request )

Request:Volley 内所有抽象要求的 基类

StringRequest:继承扩大了 Request,指定了泛型为 <String>。会将要求结果解析成 String 类型数据,并且 需要你 传入1个 Response.Listener<String> 进行解析结果数据进行回调。

JsonRequestJsonRequest<T> 抽象继承了 Request<T> 类。

  • 1. 进行了Request<T> -> JsonRequest<T> 的转换。

  • 2. 将要求结果数据 根据 “charset=utf⑻” 转换为 byte[]

  • 3. 通过覆写 getBodyContentType() 方法,将 Content-Type 设置为 application/json; charset=utf⑻

JsonObjectRequestJsonObjectRequest 继承自 JsonRequest<JSONObject>,将 JsonRequest<T> 的泛型 T,设置为 JSONObjectJsonRequest<T> 没有解析 body 内的数据为 真实的 Json 数据。所以,JsonObjectRequest 要单独将 body 内的数据解析为 JSONObject类型。

JsonArrayRequestJsonArrayRequest 继承自 JsonRequest<JSONArray>,将 JsonRequest<T> 的泛型 T,设置为 JSONArrayJsonRequest<T> 没有解析 body 内的数据为 真实的 Json 数据。所以,JsonArrayRequest 要单独将 body 内的数据解析为 JSONArray 类型。

ImageRequest:继承扩大了 Request,指定了泛型为 <Bitmap>,会将要求结果解析成 Bitmap 类型数据。并且需要你传入:

  • 1. Response.Listener<Bitmap>:将解析结果数据 进行回调。

  • 2. maxWidth:最大宽度。

  • 3. maxHeight:最大高度。

  • 4. ScaleTypeImageViewScaleType( CENTER_CROP, FIT_XY … )。

  • 5. ConfigBitmapConfig ( ALPHA_8, RGB_565, ARGB_4444, ARGB_8888 )。

  • 6. Response.ErrorListener:要求结果 Response 产生毛病的回调接口。

ClearCacheRequestClearCacheRequest 继承自 Request<Object>,用于清空 HTTP 缓存的要求。如果该要求被添加到 要求队列( RequestQueue )中,由于覆写了 getPriority() 方法,将优先级设置为 Priority.IMMEDIATE ( 立即履行 )


响应( Response )

Response:要求结果(响应)类。

  • 1. 寄存 要求结果数据缓存 key;或 毛病信息( VolleyError )

  • 2. 提供1个 Listener 接口。当接遭到 要求结果(响应)时,将 解析结果 返回。

  • 3. 再提供1个 ErrorListener 接口。产生毛病时,将调用该方法,将返回 VolleyError

  • 4. 提供1个静态方法 success(...),实例1个有 要求结果数据Response 对象

  • 5. 再提供1个静态方法 error(...),实例1个只有 毛病信息( VolleyError )Response 对象


缓存

Cache:Volley 缓存的接口。提供1些接口方法,需要子类去实现,全 Volley 中主要实现类,只有1个 DiskBasedCache

DiskBasedCacheDiskBasedCacheCache 的实现类。用于将保存缓存文件在硬盘上的指定目录中,默许的缓存大小是 5MB,缓存大小是可以手动配置的。

  • 1. 实例化了1个 LinkedHashMap<String, CacheHeader>accessOrder 设置为 true。即,依照访问顺序对数据进行排序,就是 LRU 的简单时间。容量 initialCapacity 为默许值 16,虽然手动写了 16。负载因子 loadFactor 默许值 0.75f,虽然手动写了 0.75。负载因子是 当容量超过这个百分比就会扩容,0.75f 的话,就是容量超过75%就会扩容。

  • 2.initialize() 的时候:<1>.:判断缓存目录是不是存在,不存在则创建1系列文件夹,然后返回。<2>.:存在缓存文件,开始读取缓存文件内容。每个缓存文件内容对应1个 CacheHeader。会给上述的 LinkedHashMap<String, CacheHeader>CacheHeader 缓存的内容进行添加,把文件缓存的内容映照过来。

NoCache:继承了 Cache,不做任何操作的缓存实现类。可以作为 RequestQueue 构造方法的参数,实现1个不带缓存的要求队列。


数据传递(分发)

ResponseDeliveryResponseDelivery 接口的作用 -> 从 内存缓存 或 服务器 获得要求结果数据,由 ResponseDelivery 去做结果分发和回调解理。

ExecutorDeliveryExecutorDelivery 实现了 ResponseDelivery 接口。
主要功能就是:

  • 1. 传递 要求、要求结果 or 相应毛病 和 可能有自定义的 Runnable 履行回调操作。

  • 2. 定义了1个 Executor,由于可能会有自定义的 Runnable 履行回调操作,所以需要它的存在。

  • 3. 由于有 ExecutorRunnable 的存在,但是都在子线程内。所以,还需要传入1个 UI 线程的 Handler(大多情况回调都是跟 UI 线程通讯),可以在 RequestQueue 类中 搜搜 new Handler(Looper.getMainLooper()) 关键句。

构造方法也是有趣设计:

  • 1. Handler 作为参数的构造方法。全 Volley 只有 RequestQueue 内使用,并且传入1个 UI 线程的 Handler。可以简单得出:这个构造方法可以指定( 不只是 UI 线程 )线程的 Handler 去处理这个 Runnable。看过 Handler 源码的都知道:你给我1个 Runnable,我会 拿到这个 Handler 实例化时的 Looper。再拿到 MessageQueue 去添加1条 MessageRunnable 则作为 这个 Message.callback 保存在这,然后再 Handler.dispatchMessage(…) 的时候,会履行 Message.callback.run()。所以,这里(不只是 UI 线程)线程的 Handler,说明了可以给其他线程传递( 通讯 )。

  • 2. Executor 作为参数的构造方法。这里由于 Executor 作为外部提供的参数,那末 Handler 也在外面提供了,更具有可定制性。Handler作为参数的构造方法 就是 这个 Executor 作为参数的构造方法 的升级版。由于,ExecutorDelivery 需要 ExecutorHandlerHandler 作为参数的构造方法:实例化了 ExecutorHandler 由外部提供,这里 Executor 是默许履行 handler.post(Runnable command)Executor 作为参数的构造方法:都需要外部提供。


工具

HttpHeaderParserHttp header 的解析工具类。

  • 1. 解析 Header,判断返回结果是不是需要缓存。需要缓存的话,从网络要求回来的要求结果 NetworkResponseHeader 中提取出1个用于缓存的 Cache.Entry

  • 2. 解析编码集,在 Content-Type 中获得编码集( charset ),可以根据 编码 解析 Response.databyte[] 数据。

RequestFutureRequestFuture<T> 实现了 Future<T> 接口,用于对 Request 解析数据的结果 进行 取消查询是不是完成获得结果


byte[] 流和缓存池

ByteArrayPool:1个 byte[] 缓存池,用于 byte[] 的回收再利用,减少内存分配和回收。

  • 1. 内置1个 LinkedList, 采取 LRU 的机制,最少使用的放在 index=0,最近使用的 放在 index=size()⑴

  • 2. 再内置1个 LinkedList,缓存 byte[] 缓存 List,采取根据 byte[].length 由小到大的方式排序。排序使用 Collections.binarySearch(...),对应 Comparator<byte[]> BUF_COMPARATOR

PoolingByteArrayOutputStreamPoolingByteArrayOutputStream 继承了 原生的 ByteArrayOutputStream,使用了 ByteArrayPool 回收利用1些 byte[],避免了 byte[] 的重复内存分配和回收。


重试策略

RetryPolicy:重试策略接口。具体实现可以自定义,也有默许的 DefaultRetryPolicy

DefaultRetryPolicyDefaultRetryPolicy 继承自 RetryPolicy注意的地方就是 -> mBackoffMultiplierDEFAULT_BACKOFF_MULT 用于设置 退避乘数,跟 “指数退避” 有关。


日志

VolleyLogVolleyLog 是 Volley 的1个工具类。根据 Log.isLoggable(String tag,int level) 设置 Log 的开关。
level >= INFOisLoggable 返回 true,反之则返回 false,所以,开关 默许 关闭。

  • public static final int VERBOSE = 2

  • public static final int DEBUG = 3

  • public static final int INFO = 4

  • public static final int WARN = 5

  • public static final int ERROR = 6

  • public static final int ASSERT = 7

MarkerLog:VolleyLog 提供的1个简单的静态内部 Log 类。可以通过 add(...) 添加1个 MarkerLog 的 Log 单位( Marker ),然后调用 finish(...) 打印已添加的所有 Log。


认证

Authenticator:1个身份认证接口,用于基本认证或摘要认证。在 Volley 内,是用于和身份认证,比如 OAuth。

AndroidAuthenticator:实现了 Authenticator 接口,基于 Android 上的 AccountManager,实现了认证交互。


毛病类型

VolleyError:所有 Volley 毛病的基类。继承自 Exception,用于描写 Volley 中所有的毛病异常,可以设置 NetworkResponse 和 要求消耗时间。

AuthFailureErrorAuthFailureError 继承了 VolleyError。表示:要求认证失败毛病,如 RespondCode 的 401 和 403

TimeoutErrorTimeoutError 继承了 VolleyError。表示:要求超时毛病。但是甚么都没有实现,作为1个标识存在。

ServerErrorServerError 继承了 VolleyError。表示:服务端毛病

ClientErrorClientError 扩大了 ServerError 的概念。表示:客户端毛病,即 4xx 毛病

ParseErrorParseError 继承了 VolleyError。表示:内容解析毛病

NoConnectionErrorNoConnectionError 继承了 NetworkError。表示:网络连接毛病

NetworkErrorNetworkError 继承了 VolleyError,表示:网络毛病



License

  Copyright (C) 2016 CaMnter yuanyu.camnter@gmail.com
  Copyright (C) 2015 Google Inc. All Rights Reserved.
  Copyright (C) 2012 Square, Inc.
  Copyright (C) 2011 The Android Open Source Project
  Copyright (C) 2008 The Apache Software Foundation (ASF)
  Copyright (C) 2007 The Guava Authors

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE⑵.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

------分隔线----------------------------
------分隔线----------------------------

最新技术推荐