HappyVolley
- 在非UI線程返回Response且可以配置并發(fā)線程數(shù)的Volley(未改動(dòng)源碼)<br />
- 提供Cancel單個(gè)Request的封裝
- 采用MVP標(biāo)準(zhǔn)架構(gòu)搭建Demo
前言
我知道...我懂
大家現(xiàn)在都用 OKHttp 或者 Retrofit <br />
為啥這里還要發(fā)布和二次封裝 Volley 呢?
原因有三
- 以往的成果還是做個(gè)記錄.
- Volley在沒(méi)有上傳下載等類似Task的情況下 還是有生存空間的.
- 哈哈~秘密...這個(gè)以后再談...
解決什么問(wèn)題
- Volley默認(rèn)是在UI Thread返回Response,導(dǎo)致如果還需要對(duì)數(shù)據(jù)進(jìn)行操作(比如DB,篩選,排序等相對(duì)耗時(shí)任務(wù)),則需要另起Task(非UI Thread)去做.這樣就存在新的同步問(wèn)題,甚至踏入callback深淵.<br />
解決
通過(guò)傳入ExecutorService來(lái)讓其成為單線程模型,Response依然在非UI Thread返回.這樣數(shù)據(jù)層可以繼續(xù)對(duì)其進(jìn)行操作.
當(dāng)結(jié)果返回到業(yè)務(wù)層的時(shí)候 再通知GUI更新即可(Handler EventBus等隨意了). - Volley默認(rèn)采用4個(gè)線程作為線程池控制,無(wú)法修改.<br />
解決
我們通過(guò)Volley構(gòu)造方法<br />
/**
* Creates the worker pool. Processing will not begin until {@link #start()} is called.
*
* @param cache A Cache to use for persisting responses to disk
* @param network A Network interface for performing HTTP requests
* @param threadPoolSize Number of network dispatcher threads to create
* @param delivery A ResponseDelivery interface for posting responses and errors
*/
public RequestQueue(Cache cache, Network network, int threadPoolSize,
ResponseDelivery delivery) {
mCache = cache;
mNetwork = network;
mDispatchers = new NetworkDispatcher[threadPoolSize];
mDelivery = delivery;
}
去創(chuàng)建一個(gè)新的RequestQueue對(duì)象即可解決這個(gè)問(wèn)題.
3. Demo中還附送福利 <br />
BaseRequest類中贈(zèng)送 Cancel的封裝 <br />
可以根據(jù)傳入的Tag Cancel單個(gè)Request 或者 Cancel All Request
/**
* 取消所有請(qǐng)求
*/
public static void cancelAllRequest() {
HappyRequestQueue.getInstance().getRequestQueue().cancelAll(new RequestQueue.RequestFilter() {
@Override
public boolean apply(Request<?> request) {
Log.w(TAG, "Cancel All Request");
return true;
}
});
}
/**
* 根據(jù)tag來(lái)取消符合tag的請(qǐng)求
*
* @param tag String
*/
public static void cancelRequest(final String tag) {
// 取消已經(jīng)存在的請(qǐng)求力崇,防止重復(fù)請(qǐng)求
HappyRequestQueue.getInstance().getRequestQueue().cancelAll(new RequestQueue.RequestFilter() {
@Override
public boolean apply(Request<?> request) {
boolean cancel = tag.equals(request.getTag());
if (cancel) {
Log.w(TAG, "Cancel Old Request: " + tag);
}
return cancel;
}
});
}
工程描述
本來(lái)是說(shuō)就放個(gè)HappyRequestQueue類好了.反正大家也看得懂.
后來(lái)想想算了咱們還是做個(gè)Demo吧.
誰(shuí)讓哥做人這么厚道呢...
那就開(kāi)始寫(xiě)唄...
啪啪啪~
工程一定要基于Android Studio才溜得飛起
MVP架構(gòu)搞起來(lái) 各種Niubility... <br />
網(wǎng)絡(luò)請(qǐng)求庫(kù)的Demo 肯定要請(qǐng)求點(diǎn)啥啊...恩對(duì)~
但是...天吶~~~哪有API來(lái)做Demo測(cè)試呢?
好在我機(jī)智...找到淘寶有個(gè)手機(jī)號(hào)的API接口 不用像百度那樣非要appkey
https://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=手機(jī)號(hào) <br />
坑爹的是這個(gè)接口不能用POST,以往封裝好的JSONRequest無(wú)法直接使用...
不過(guò)這也難不倒哥...改就是了 , GET分分鐘搞定...
雖然顯得不夠優(yōu)雅.
但是我們的重點(diǎn)不是這一層啊...
做完后的樣子...<br />
使用說(shuō)明
因?yàn)槭莻€(gè)單例類
直接使用
HappyRequestQueue.getInstance().addRequest(YourRequest);
YourRequest extends com.android.volley.Request<T> <br />
即可
具體代碼
public class HappyRequestQueue {
public final String TAG = "RequesterDefaultTag";
/**
* Default on-disk cache directory.
*/
private static final String DEFAULT_CACHE_DIR = "volley";
/**
* Number of network request dispatcher threads to start.
*/
private static final int DEFAULT_NETWORK_THREAD_POOL_SIZE = 1;
RequestQueue mRequestQueue;
ExecutorService executorService = Executors.newFixedThreadPool(1);
/**
* getInstance
*
* @return RequestQueue
*/
public static HappyRequestQueue getInstance() {
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder {
static final HappyRequestQueue INSTANCE = new HappyRequestQueue();
}
/**
* 異步請(qǐng)求
*
* @param request Request
* @param <T> Request
*/
public <T> void addRequest(Request<T> request) {
addRequest(request, null);
}
/**
* 異步請(qǐng)求
*
* @param request Request
* @param tag tag用于區(qū)分是否同一個(gè)請(qǐng)求
* @param <T> Request
*/
public <T> void addRequest(Request<T> request, Object tag) {
request.setTag(tag == null ? TAG : tag);
getRequestQueue().add(request);
}
/**
* 同步請(qǐng)求
*
* @param request Request
* @param <T> Request
* @return JSONObject
*/
public <T> JSONObject addSyncRequest(Request<T> request) {
return addSyncRequest(request, null);
}
/**
* 同步請(qǐng)求
*
* @param request Request
* @param tag tag用于區(qū)分是否同一個(gè)請(qǐng)求
* @param <T> Request
* @return JSONObject
*/
public <T> JSONObject addSyncRequest(Request<T> request, Object tag) {
request.setTag(tag == null ? TAG : tag);
RequestFuture<JSONObject> future = RequestFuture.newFuture();
getRequestQueue().add(request);
try {
return future.get();
} catch (InterruptedException | ExecutionException e) {
Log.e(TAG, e.getMessage());
}
return null;
}
public com.android.volley.RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
//mRequestQueue = Volley.newRequestQueue(MyApplication.getInstance().getApplicationContext());
mRequestQueue = newRequestQueue(MyApplication.getInstance().getApplicationContext());
}
return mRequestQueue;
}
/**
* 自定義Volley請(qǐng)求Queue
*
* @param context Context
* @return RequestQueue
*/
public RequestQueue newRequestQueue(Context context) {
File cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR);
Network network = new BasicNetwork(new HurlStack());
//**重點(diǎn)就是在這里new ExecutorDelivery(executorService),是不是很簡(jiǎn)單**
RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir),
network,
DEFAULT_NETWORK_THREAD_POOL_SIZE,
new ExecutorDelivery(executorService));
queue.start();
return queue;
}
}
鏈接
1.https://github.com/xmagicj/HappyVolley<br />
怎樣直接添加License?誰(shuí)可以分享一下?