XVolley-基于Volley的封装的工具类

1.Volley源码分析(一)
2.Volley源码分析(二)
3.Volley源码分析(三)
4.XVolley-基于Volley的封装的工具类

前面几篇博客分析了Volley的源码,加上最近在看《Head First设计模式》这本书(不得不说老外的书是真的不错,推荐),于是基于鸿洋大神的OkhttpUtil的源码和OkHttp的源码,加上自己的理解,封装了这么一个工具类。

一、功能

1.GET
2.POST
3.post传json
4.post传文件(不支持大文件类型)
5.自定义拦截器
6.gson
7.配置URL
8.全局URL,HEADER,拦截器

二、优化

1.单例模式保证全局请求队列
2.weakreference持有Activity,支持onFinish()回调,防止内存泄漏
3.支持全局配置URL,HEADER
4.链式调用
5.增加过滤器

三、未来构思

1.支持cookie
2.支持大文件
3.支持上传文件进度回调
4.支持https
5.构思ing...

How to:

Step 1. Add the JitPack repository to your build file
Add it in your root build.gradle at the end of repositories:

    allprojects {
        repositories {
            ...
            maven { url 'https://jitpack.io' }
        }
    }

Step 2. Add the dependency

dependencies {
            compile 'com.github.sdfdzx:XVolley:v1.0.1'
    }

Usage

1.在Application中初始化请求队列。

 XVolley.create(getApplicationContext());

2.在Application中全局配置Header,URL,Intercepter.(可选)

通过调用init(Config config)方法,Config通过BaseConfigBuilder构建。

Map<String, String> header = new HashMap<>();
header.put("user-token", "AEUHY98QIASUDH");
BaseConfigBuilder config = new BaseConfigBuilder();
config.baseUrl("http://127.0.0.1/get.php")
      .addParam("client", "Android")
      .addParam("position", "北京")
      .addHeaders(header)
      .addIntercept(new Interceptor() {
          @Override
          public Request intercept(Chain chain) {
              Request request = chain.request();
              LogUtil.log("intercept","baseIntercept:"+request.getUrl());
              return request;
          }
       });
XVolley.create(getApplicationContext())
       .init(config.build());

3.GET请求

XVolley.getInstance()
       .doGet()
       .url("http://127.0.0.1/get.php")
       .addParam("name", "xuan")
       .build()
       .execute(this, new CallBack<String>() {
           @Override
           public void onSuccess(Context context, String response) {
           }
       });

这里的.url()方法会覆盖掉全局配置的URL,如果使用全局的URL,直接调用addParam方法即可,根据自己需求使用。

4.POST请求

        XVolley.getInstance()
                .doPost()
                .url("http://127.0.0.1/post.php")
                .addParam("user", "xuan")
                .build()
                .execute(this, new CallBack<String>() {
                    @Override
                    public void onSuccess(Context context, String response) {
                        Log.e("Success", response);
                    }
                });

5.POST请求传String字符串

        weather weather = new weather();
        weather.setCity("北京");
        weather.setMessage("这是一条带json的post请求");

        //post请求带json
        XVolley.getInstance()
                .doPostString()
                .url("http://127.0.0.1/stringpost.php")
                .content(new Gson().toJson(weather))
                .build()
                .execute(this,new CallBack<String>(){
                    @Override
                    public void onSuccess(Context context, String response) {
                        Log.e("Success", response);
                    }
                });

6.上传文件(小文件,字节流实现方式)

支持多文件,多参数。

XVolley.getInstance()
       .doPostFile()
       .url("http://127.0.0.1/filex.php")
       .addParam("name","xuan")
       .addFile("txt", "bb.txt", Environment.getExternalStorageDirectory() + "/bb" +
                                ".txt")
       .addFile("png", "aa.txt", Environment.getExternalStorageDirectory() + "/aa" +
                                ".png")
       .build()
       .execute(MainActivity.this, new CallBack<String>() {
           @Override
           public void onSuccess(Context context, String response) {
                LogUtil.log("success",response);
           }
        });

7.Gson解析

只需要在链式调用中加上goGson(Class c)方法,传入Gson对应的class类型。所有类型请求都可以。

XVolley.getInstance()       
        .doGet()
        .url(       "http://www.sojson.com/open/api/weather/json.shtml")
       .addParam("city", "北京")
       .addHeaders(header)
       .goGson(weather.class)
       .build()
    .execute(MainActivity.this, new CallBack<weather>() {
        @Override
        public void onSuccess(Context context, weather response) {
        Log.e("Success", response.getCity());
            }
        });

8.过滤器。

实现Interceptor接口的intercept方法。

public interface Interceptor {
    Request intercept(Chain chain);

    interface Chain {
        Request request();
    }
    }

(1)支持全局过滤器

Map<String, String> header = new HashMap<>();
header.put("user-token", "AEUHY98QIASUDH");
BaseConfigBuilder config = new BaseConfigBuilder();
        config.baseUrl("http://127.0.0.1/get.php")
      .addParam("client", "Android")
      .addParam("position", "北京")
      .addHeaders(header)
      .addIntercept(new Interceptor() {
          @Override
          public Request intercept(Chain chain) {
               Request request = chain.request();
               LogUtil.log("intercept","baseIntercept:"+request.getUrl());
               return request;
               }
       });
XVolley.create(getApplicationContext())
       .init(config.build());

(2)支持单独过滤器

Map<String, String> header = new HashMap<>();
header.put("APP-Secret", "ad12msa234das232in");
XVolley.getInstance()
       .doGet()
       .url(
"http://www.sojson.com/open/api/weather/json.shtml")
       .addParam("city", "北京")
       .addHeaders(header)
       .goGson(weather.class)
       .build()
       .addInterceptor(new Interceptor() {
           @Override
           public Request intercept(Chain chain) {                      LogUtil.log("intercept","custom");
               Request request = chain.request();
               String url = request.getUrl();
               if (url.contains("sojson")) {
                   request.cancel();
                   return request;
                }
                return request;
            }
        })
        .execute(MainActivity.this, new CallBack<weather>() {
             @Override
             public void onSuccess(Context context, weather response) {
                  Log.e("Success", response.getCity());
             }
        });

(3)支持全局+单独
递归调用,先调用单独的过滤器再调用全局过滤器

9.CallBack

可以实现ICallBack接口实现所有方法

public interface ICallBack<T> {
    void onBefore();
    void onSuccess(Context context, T response);
    void onError(VolleyError error);
    void onAfter();
    void onFinish();
    }

或者实现CallBack类,实现对应需要的方法。

public abstract class CallBack<T> implements ICallBack<T> {
    @Override
    public void onBefore() {
    }
    @Override
    public void onSuccess(Context context, T response) {
    }
    @Override
    public void onError(VolleyError error) {
    }
    @Override
    public void onAfter() {
    }
    @Override
    public void onFinish() {
    }
    }

onFinish方法对应请求过程中Activity销毁的回调,可用于回收资源,防止内存泄漏。

10.Listener

内部Listener使用WeakReference持有Activity对象,防止内存泄漏。

public abstract class WeakListener{
    final WeakReference<Activity> activityWeakReference;
    final ICallBack callBack;
    public WeakListener(Context activity, ICallBack callBack) {
        activityWeakReference = new WeakReference<Activity>((Activity) activity);
        this.callBack = callBack;
    }
    }

最后给上Github地址:https://github.com/sdfdzx/XVolley

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

推荐阅读更多精彩内容