HappyVolley

HappyVolley

  • 在非UI线程返回Response且可以配置并发线程数的Volley(未改动源码)<br />
  • 提供Cancel单个Request的封装
  • 采用MVP标准架构搭建Demo

前言

我知道...我懂
大家现在都用 OKHttp 或者 Retrofit <br />
为啥这里还要发布和二次封装 Volley 呢?

原因有三

  • 以往的成果还是做个记录.
  • Volley在没有上传下载等类似Task的情况下 还是有生存空间的.
  • 哈哈~秘密...这个以后再谈...

解决什么问题

  1. Volley默认是在UI Thread返回Response,导致如果还需要对数据进行操作(比如DB,筛选,排序等相对耗时任务),则需要另起Task(非UI Thread)去做.这样就存在新的同步问题,甚至踏入callback深渊.<br />
    解决
    通过传入ExecutorService来让其成为单线程模型,Response依然在非UI Thread返回.这样数据层可以继续对其进行操作.
    当结果返回到业务层的时候 再通知GUI更新即可(Handler EventBus等随意了).
  2. Volley默认采用4个线程作为线程池控制,无法修改.<br />
    解决
    我们通过Volley构造方法<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;
        }

去创建一个新的RequestQueue对象即可解决这个问题.

3. Demo中还附送福利 <br />
BaseRequest类中赠送 Cancel的封装 <br />
可以根据传入的Tag Cancel单个Request 或者 Cancel All Request

    /**
     * 取消所有请求
     */
    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;
            }
        });
    }

    /**
     * 根据tag来取消符合tag的请求
     *
     * @param tag String
     */
    public static void cancelRequest(final String tag) {
        // 取消已经存在的请求,防止重复请求
        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;
            }
        });
    }

工程描述

本来是说就放个HappyRequestQueue类好了.反正大家也看得懂.
后来想想算了咱们还是做个Demo吧.
谁让哥做人这么厚道呢...

那就开始写呗...
啪啪啪~

工程一定要基于Android Studio才溜得飞起
MVP架构搞起来 各种Niubility... <br />

Paste_Image.png

网络请求库的Demo 肯定要请求点啥啊...恩对~
但是...天呐~~~哪有API来做Demo测试呢?

好在我机智...找到淘宝有个手机号的API接口 不用像百度那样非要appkey

https://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=手机号 <br />

坑爹的是这个接口不能用POST,以往封装好的JSONRequest无法直接使用...
不过这也难不倒哥...改就是了 , GET分分钟搞定...
虽然显得不够优雅.
但是我们的重点不是这一层啊...

做完后的样子...<br />

Paste_Image.png

使用说明

因为是个单例类
直接使用

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();
    }

    /**
     * 异步请求
     *
     * @param request Request
     * @param <T>     Request
     */
    public <T> void addRequest(Request<T> request) {
        addRequest(request, null);
    }

    /**
     * 异步请求
     *
     * @param request Request
     * @param tag     tag用于区分是否同一个请求
     * @param <T>     Request
     */
    public <T> void addRequest(Request<T> request, Object tag) {
        request.setTag(tag == null ? TAG : tag);
        getRequestQueue().add(request);
    }

    /**
     * 同步请求
     *
     * @param request Request
     * @param <T>     Request
     * @return JSONObject
     */
    public <T> JSONObject addSyncRequest(Request<T> request) {
        return addSyncRequest(request, null);
    }

    /**
     * 同步请求
     *
     * @param request Request
     * @param tag     tag用于区分是否同一个请求
     * @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请求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());
        //**重点就是在这里new ExecutorDelivery(executorService),是不是很简单**
        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?谁可以分享一下?

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,423评论 6 491
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,147评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,019评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,443评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,535评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,798评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,941评论 3 407
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,704评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,152评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,494评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,629评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,295评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,901评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,742评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,978评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,333评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,499评论 2 348

推荐阅读更多精彩内容