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
Flow 和 agera
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
Flow 和 agera
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'
}
將 原版的 google/volley 中 網絡實現層 的 Apache HttpClient 和 原生的 HttpUrlConnection 都移除。
換成 square/okhttp3 作爲實現網絡請求。
savevolley-hurl
gradle
dependencies {
// for hurl
compile 'com.camnter.savevolley:hurl:1.6.6'
}
API >= 9
移除了 原版 google/volley 中的,所有相關與 HttpClient 的邏輯,全版本的網絡通信接入到 HttpUrlConnection 內。
savevolley-network-core
由於,網絡底層實現( 網絡請求實現 )可以通過不同框架( okhttp、HttpUrlConnection、Apache HttpClient … )去實現。
所以,只是拿到 不同框架的響應結果。
但是 Volley 的緩存層是 通用的,所以需要定義一套 通用的 HTTP Response API,然後將 不同框架的響應結果 轉換爲
通用的 HTTP Response API。
這個模塊還需要與 savevolley-network-adapter 的子模塊( savevolley-network-okhttp3-adapter, savevolley-network-hurl-adapter )一起協作。
savevolley-network-adapter
目的是爲了定義一些接口: 不同框架的響應結果 >> 通用的 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
作用: 提供一些 hurl 與 agera 協作需要的基礎類。
extensions / savevolley-okhttp3-agera-core
作用: 提供一些 okhttp3 與 agera 協作需要的基礎類。
extensions / agera-gson / savevolley-okhttp3-agera-gson
作用: agera >> savevolley-okhttp3 << gson , 爲 savevolley-okhttp3 橋接了 agera 和 gson 。
extensions / agera-gson / savevolley-hurl-agera-gson
作用: agera >> savevolley-hurl << gson , 爲 savevolley-hurl 橋接了 agera 和 gson 。
extensions / agera-fastjson / savevolley-okhttp3-agera-fastjson
savevolley-okhttp3-agera-fastjson
作用: agera >> savevolley-okhttp3 << fastjson , 爲 savevolley-okhttp3 橋接了 agera 和 fastjson 。
extensions / agera-fastjson / savevolley-hurl-agera-fastjson
savevolley-hurl-agera-fastjson
作用: agera >> savevolley-hurl << fastjson , 爲 savevolley-hurl 橋接了 agera 和 fastjson 。
extensions / fastjson / savevolley-hurl-fastjson
作用: fastjson >> savevolley-hurl 。
extensions / fastjson / savevolley-okhttp3-fastjson
作用: fastjson >> savevolley-okhttp3 。
extensions / gson / savevolley-hurl-gson
作用: gson >> savevolley-hurl 。
extensions / 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
原版的 google/volley,全部代碼加上了註釋。
入口
Volley:Volley 框架使用的入口,用於創建一個 RequestQueue。
1.
RequestQueue queue = Volley.newRequestQueue(this)
2.
queue.add(request)
RequestQueue:RequestQueue
被定義爲 請求隊列。用於操作 緩存請求執行線程( 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
的形式,最後 傳遞Request
和Response
數據。2. 失敗,失敗的話,一般會拋出異常,然後進行 記錄請求時長 和 傳遞錯誤( VolleyError )。
CacheDispatcher:是用於處理 Volley 中的緩存數據 的 緩存線程。
1.1. 檢查緩存。從 緩存
Request
隊列中取出 緩存 Request,然後 根據 緩存 Request CacheKey 去硬盤緩存(DiskBasedCache
)映射過來的內存緩存中尋找 是否存在Entry
(Response
)。1.2. 存在的話,通過
DefaultRetryPolicy
回傳相關數據。1.3. 存在但緩存需要刷新的話,放入 網絡 Request 隊列 內,會在
NetworkDispatcher
的循環體中被用來 重新請求。1.4. 不存在的話,將該 Request,放入 網絡 Request 隊列 內,會在
NetworkDispatcher
的循環體中被用來 重新請求。2.
CacheDispatcher
只做緩存相關的操作,不做網絡的操作。所以CacheDispatcher
,只涉及到 緩存 Response 的增刪改查 以及 查詢成功後的數據分發( 傳遞 )。
網絡請求 使用層
Network:在 Volley 中,是處理 網絡請求 的表層使用接口。只有一個方法:performRequest(...)
執行請求,
BasicNetwork:BasicNetwork
是 目前 Volley 內,Network
接口的唯一實現類,在 Volley 內,處理了 網絡請求 的表層使用接口。實現了 performRequest(...)
方法的具體功能,performRequest(...)
要做的事情是:
1. 調用
HttpStack
接口的實現類 (HurlStack
,HttpClientStack
) 去執行網絡請求實現,會拿到一個Apache HttpResponse
。2. 然後,將 Apache HttpResponse -> Volley NetworkResponse 進行轉化,並返回。
網絡請求 實現層
HttpStack:HttpStack
是 Volley 內 執行 網絡請求 的 底層實現接口。實現類有:
1.
HttpClientStack
:基於org.apache.http
的網絡請求實現。負責 系統版本 2.3 以下 的 網絡請求實現。2.
HurlStack
:基於HttpURLConnection
的網絡請求實現。負責 系統版本 2.3 以上 的 網絡請求實現。
HttpClientStack:HttpClientStack
實現了 HttpStack
接口。封裝了基於 org.apache.http.HttpClient
提供的網絡實現( performRequest(...)
),處理了 2.3 版本以下的 各種網絡請求( GET、POST、DEL … )的實現。
HurlStack:HurlStack
實現了 HttpStack
接口。封裝了基於 javax.net.ssl.HttpsURLConnection
提供的網絡實現( performRequest(...)
),處理了 2.3 版本以上的 各種網絡請求( GET、POST、DEL … )的實現。
請求( Request )
Request:Volley 內所有抽象請求的 基類。
StringRequest:繼承擴展了 Request
,指定了泛型爲 <String>
。會將請求結果解析成 String
類型數據,並且 需要你 傳入一個 Response.Listener<String>
進行解析結果數據進行回調。
JsonRequest:JsonRequest<T>
抽象繼承了 Request<T>
類。
1. 進行了
Request<T>
->JsonRequest<T>
的轉換。2. 將請求結果數據 根據 “charset=utf-8” 轉換爲 byte[]。
3. 通過覆寫
getBodyContentType()
方法,將 Content-Type 設置爲 application/json; charset=utf-8。
JsonObjectRequest:JsonObjectRequest
繼承自 JsonRequest<JSONObject>
,將 JsonRequest<T>
的泛型 T,設置爲 JSONObject
。JsonRequest<T>
沒有解析 body 內的數據爲 真正的 Json 數據。所以,JsonObjectRequest
要單獨將 body 內的數據解析爲 JSONObject
類型。
JsonArrayRequest:JsonArrayRequest
繼承自 JsonRequest<JSONArray>
,將 JsonRequest<T>
的泛型 T,設置爲 JSONArray
。JsonRequest<T>
沒有解析 body 內的數據爲 真正的 Json 數據。所以,JsonArrayRequest
要單獨將 body 內的數據解析爲 JSONArray
類型。
ImageRequest:繼承擴展了 Request
,指定了泛型爲 <Bitmap>
,會將請求結果解析成 Bitmap 類型數據。並且需要你傳入:
1.
Response.Listener<Bitmap>
:將解析結果數據 進行回調。2.
maxWidth
:最大寬度。3.
maxHeight
:最大高度。4.
ScaleType
:ImageView
的ScaleType
( CENTER_CROP, FIT_XY … )。5.
Config
:Bitmap 的Config
( ALPHA_8, RGB_565, ARGB_4444, ARGB_8888 )。6.
Response.ErrorListener
:請求結果 Response 發生錯誤的回調接口。
ClearCacheRequest:ClearCacheRequest
繼承自 Request<Object>
,用於清空 HTTP 緩存的請求。如果該請求被添加到 請求隊列( RequestQueue )中,由於覆寫了 getPriority()
方法,將優先級設置爲 Priority.IMMEDIATE ( 立即執行 )。
響應( Response )
Response:請求結果(響應)類。
1. 存放 請求結果數據 和 緩存 key;或者 錯誤信息( VolleyError )。
2. 提供一個
Listener
接口。當接受到 請求結果(響應)時,將 解析結果 返回。3. 再提供一個
ErrorListener
接口。發生錯誤時,將調用該方法,將返回VolleyError
。4. 提供一個靜態方法
success(...)
,實例一個有 請求結果數據 的 Response 對象。5. 再提供一個靜態方法
error(...)
,實例一個只有 錯誤信息( VolleyError ) 的Response
對象
緩存
Cache:Volley 緩存的接口。提供一些接口方法,需要子類去實現,全 Volley 中主要實現類,只有一個 DiskBasedCache
。
DiskBasedCache:DiskBasedCache
是 Cache
的實現類。用於將保存緩存文件在硬盤上的指定目錄中,默認的緩存大小是 5MB,緩存大小是可以手動配置的。
1. 實例化了一個
LinkedHashMap<String, CacheHeader>
,accessOrder
設置爲 true。即,按照訪問順序對數據進行排序,就是 LRU 的簡單時間。容量initialCapacity
爲默認值 16,雖然手動寫了 16。負載因子loadFactor
默認值 0.75f,雖然手動寫了 0.75。負載因子是 當容量超過這個百分比就會擴容,0.75f 的話,就是容量超過75%就會擴容。2. 在
initialize()
的時候:<1>.:判斷緩存目錄是否存在,不存在則創建一系列文件夾,然後返回。<2>.:存在緩存文件,開始讀取緩存文件內容。每一個緩存文件內容對應一個CacheHeader
。會給上述的LinkedHashMap<String, CacheHeader>
,CacheHeader
緩存的內容進行添加,把文件緩存的內容映射過來。
NoCache:繼承了 Cache
,不做任何操作的緩存實現類。可以作爲 RequestQueue
構造方法的參數,實現一個不帶緩存的請求隊列。
數據傳遞(分發)
ResponseDelivery:ResponseDelivery 接口的作用 -> 從 內存緩存 或者 服務器 取得請求結果數據,由 ResponseDelivery
去做結果分發以及回調處理。
ExecutorDelivery:ExecutorDelivery
實現了 ResponseDelivery
接口。
主要功能就是:
1. 傳遞 請求、請求結果 or 相應錯誤 以及 可能有自定義的
Runnable
執行回調操作。2. 定義了一個
Executor
,因爲可能會有自定義的Runnable
執行回調操作,所以需要它的存在。3. 因爲有
Executor
和Runnable
的存在,但是都在子線程內。所以,還需要傳入一個 UI 線程的Handler
(大多情況回調都是跟 UI 線程通信),可以在RequestQueue
類中 搜搜 new Handler(Looper.getMainLooper()) 關鍵句。
構造方法也是有趣設計:
1.
Handler
作爲參數的構造方法。全 Volley 只有RequestQueue
內使用,並且傳入一個 UI 線程的Handler
。可以簡單得出:這個構造方法可以指定( 不只是 UI 線程 )線程的Handler
去處理這個Runnable
。看過Handler
源碼的都知道:你給我一個Runnable
,我會 拿到這個Handler
實例化時的Looper
。再拿到MessageQueue
去添加一條Message
,Runnable
則作爲 這個Message.callback
保存在這,然後再 Handler.dispatchMessage(…) 的時候,會執行 Message.callback.run()。所以,這裏(不只是 UI 線程)線程的Handler
,說明了可以給其他線程傳遞( 通信 )。2.
Executor
作爲參數的構造方法。這裏由於Executor
作爲外部提供的參數,那麼Handler
也在外面提供了,更具有可定製性。Handler
作爲參數的構造方法 就是 這個Executor
作爲參數的構造方法 的升級版。因爲,ExecutorDelivery
需要Executor
和Handler
,Handler
作爲參數的構造方法:實例化了Executor
,Handler
由外部提供,這裏Executor
是默認執行 handler.post(Runnable command)。Executor
作爲參數的構造方法:都需要外部提供。
工具
HttpHeaderParser:Http header 的解析工具類。
1. 解析
Header
,判斷返回結果是否需要緩存。需要緩存的話,從網絡請求回來的請求結果NetworkResponse
的Header
中提取出一個用於緩存的Cache.Entry
。2. 解析編碼集,在 Content-Type 中獲取編碼集( charset ),可以根據 編碼 解析 Response.data 的 byte[] 數據。
RequestFuture:RequestFuture<T>
實現了 Future<T>
接口,用於對 Request
解析數據的結果 進行 取消、查詢是否完成、獲取結果。
byte[] 流和緩存池
ByteArrayPool:一個 byte[] 緩存池,用於 byte[] 的回收再利用,減少內存分配和回收。
1. 內置一個
LinkedList
, 採用 LRU 的機制,最少使用的放在index=0
,最近使用的 放在index=size()-1
。2. 再內置一個
LinkedList
,緩存 byte[] 緩存 List,採用根據 byte[].length 由小到大的方式排序。排序使用Collections.binarySearch(...)
,對應Comparator<byte[]> BUF_COMPARATOR
。
PoolingByteArrayOutputStream:PoolingByteArrayOutputStream
繼承了 原生的 ByteArrayOutputStream
,使用了 ByteArrayPool
回收利用一些 byte[],防止了 byte[] 的重複內存分配和回收。
重試策略
RetryPolicy:重試策略接口。具體實現可以自定義,也有默認的 DefaultRetryPolicy
。
DefaultRetryPolicy:DefaultRetryPolicy
繼承自 RetryPolicy
。注意的地方就是 -> mBackoffMultiplier
和 DEFAULT_BACKOFF_MULT
用於設置 退避乘數,跟 “指數退避” 有關。
日誌
VolleyLog:VolleyLog
是 Volley 的一個工具類。根據 Log.isLoggable(String tag,int level)
設置 Log 的開關。
level >= INFO 時 isLoggable
返回 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 提供的一個簡單的靜態內部 Log 類。可以通過 add(...)
添加一個 MarkerLog
的 Log 單位( Marker
),然後調用 finish(...)
打印已經添加的所有 Log。
認證
Authenticator:一個身份認證接口,用於基本認證或者摘要認證。在 Volley 內,是用於和身份認證,比如 OAuth。
AndroidAuthenticator:實現了 Authenticator
接口,基於 Android 上的 AccountManager
,實現了認證交互。
錯誤類型
VolleyError:所有 Volley 錯誤的基類。繼承自 Exception
,用於描述 Volley 中所有的錯誤異常,可以設置 NetworkResponse
和 請求消耗時間。
AuthFailureError:AuthFailureError
繼承了 VolleyError
。表示:請求認證失敗錯誤,如 RespondCode 的 401 和 403。
TimeoutError:TimeoutError
繼承了 VolleyError
。表示:請求超時錯誤。但是什麼都沒有實現,作爲一個標識存在。
ServerError:ServerError
繼承了 VolleyError
。表示:服務端錯誤。
ClientError:ClientError
擴展了 ServerError
的概念。表示:客戶端錯誤,即 4xx 錯誤。
ParseError:ParseError
繼承了 VolleyError
。表示:內容解析錯誤。
NoConnectionError:NoConnectionError
繼承了 NetworkError
。表示:網絡連接錯誤。
NetworkError:NetworkError
繼承了 VolleyError
,表示:網絡錯誤。
License
Copyright (C) 2016 CaMnter [email protected]
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-2.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.