xUtils使用详解(二)

上篇文章,我们讲解了xUtils的注解、图片加载以及数据库操作,如果你未了解,请先查看xUtils使用详解(一)。今天就来看看xUtils的另一主要功能,网络模块!

HttpUtils模块。

(1).支持同步,异步方式的请求;
(2).支持大文件上传,上传大文件不会oom;
(3).支持GET,POST,PUT,MOVE,COPY,DELETE,HEAD,OPTIONS,TRACE,CONNECT请求;
(4).下载支持301/302重定向,支持设置是否根据Content-Disposition重命名下载的文件;
(5).返回文本内容的请求(默认只启用了GET请求)支持缓存,可设置默认过期时间和针对当前请求的过期时间。

1.get请求。

首先需要介绍RequestParams类。

RequestParams 是网络请求参数实体,负责将网络请求中的各种数据组装。它提供了好几种构造方法,其中比较常用的是RequestParams(String uri)方法,参数是请求地址,

    /**
     * @param uri 不可为空
     */
    public RequestParams(String uri) {
        this(uri, null, null, null);
    }

它的内部其实还是调用了它的RequestParams(String uri, ParamsBuilder builder, String[] signs, String[] cacheKeys)方法,

  /**
     * @param uri       不可为空
     * @param builder
     * @param signs
     * @param cacheKeys
     */
    public RequestParams(String uri, ParamsBuilder builder, String[] signs, String[] cacheKeys) {
        if (uri != null && builder == null) {
            builder = new DefaultParamsBuilder();
        }
        this.uri = uri;
        this.signs = signs;
        this.cacheKeys = cacheKeys;
        this.builder = builder;
    }

它提供了好几种添加参数的方法,

(1).addQueryStringParameter(String name, String value)  添加参数至URL中,用于GET请求。

 /**
     * 添加参数至Query String
     *
     * @param name
     * @param value
     */
    public void addQueryStringParameter(String name, String value) {
        if (!TextUtils.isEmpty(name)) {
            this.queryStringParams.add(new KeyValue(name, value));
        }
    }

(2).addBodyParameter(String name, String value)  添加参数至body中,只有POST, PUT, PATCH, DELETE请求支持。

    /**
     * 添加参数至Body
     *
     * @param name
     * @param value
     */
    public void addBodyParameter(String name, String value) {
        if (!TextUtils.isEmpty(name)) {
            this.bodyParams.add(new KeyValue(name, value));
        } else {
            this.bodyContent = value;
        }
    }

(3).addBodyParameter(String name, File value)  用于上传文件。

    /**
     * 添加body参数
     */
    public void addBodyParameter(String name, File value) {
        addBodyParameter(name, value, null, null);
    }

(4).addParameter(String name, Object value)  根据请求方法不同,会将参数添加到不同的地方。例如GET请求,添加参数至URL中;而POST, PUT, PATCH, DELETE请求,则将参数添加至body中。

  /**
     * 添加请求参数(根据请求谓词, 将参数加入QueryString或Body.)
     *
     * @param name  参数名
     * @param value 可以是String, File, InputStream 或 byte[]
     */
    public void addParameter(String name, Object value) {
        if (value == null) return;

        if (method == null || HttpMethod.permitsRequestBody(method)) {
            if (!TextUtils.isEmpty(name)) {
                if (value instanceof File
                        || value instanceof InputStream
                        || value instanceof byte[]) {
                    this.fileParams.add(new KeyValue(name, value));
                } else {
                    if (value instanceof Iterable) {
                        for (Object item : (Iterable) value) {
                            this.bodyParams.add(new ArrayItem(name, item));
                        }
                    } else if (value instanceof JSONArray) {
                        JSONArray array = (JSONArray) value;
                        int len = array.length();
                        for (int i = 0; i < len; i++) {
                            this.bodyParams.add(new ArrayItem(name, array.opt(i)));
                        }
                    } else if (value.getClass().isArray()) {
                        int len = Array.getLength(value);
                        for (int i = 0; i < len; i++) {
                            this.bodyParams.add(new ArrayItem(name, Array.get(value, i)));
                        }
                    } else {
                        this.bodyParams.add(new KeyValue(name, value));
                    }
                }
            } else {
                this.bodyContent = value.toString();
            }
        } else {
            if (!TextUtils.isEmpty(name)) {
                if (value instanceof Iterable) {
                    for (Object item : (Iterable) value) {
                        this.queryStringParams.add(new ArrayItem(name, item));
                    }
                } else if (value.getClass().isArray()) {
                    int len = Array.getLength(value);
                    for (int i = 0; i < len; i++) {
                        this.queryStringParams.add(new ArrayItem(name, Array.get(value, i)));
                    }
                } else {
                    this.queryStringParams.add(new KeyValue(name, value));
                }
            }
        }
    }

下面给出一个请求事例,代码如下,

    RequestParams params = new RequestParams(url);
    params.addQueryStringParameter("username","abc");//设置参数
    params.addQueryStringParameter("password","123");//设置参数
    x.http().get(params, new Callback.CommonCallback() {
        @Override
        public void onSuccess(String result) {

        }
        //请求异常后的回调方法
        @Override
        public void onError(Throwable ex, boolean isOnCallback) {
        }
        //主动调用取消请求的回调方法
        @Override
        public void onCancelled(CancelledException cex) {
        }
        @Override
        public void onFinished() {

        }
    });

2.post请求。

例如代码如下,

    RequestParams params = new RequestParams(url);
    params.addBodyParameter("username","zxw");//设置参数
    params.addParameter("password","123456");//设置参数
    params.addHeader("head","android"); //添加一个请求头
    x.http().post(params, new Callback.CommonCallback() {
        @Override
        public void onSuccess(String result) {
        }
        @Override
        public void onError(Throwable ex, boolean isOnCallback) {
        }
        @Override
        public void onCancelled(CancelledException cex) {
        }
        @Override
        public void onFinished() {
        }
    });

xUtils已经封装了GET请求和POST请求。如果还需要其他请求方式,那么该怎么操作呢?

3.其他请求方式。

使用案例代码如下,

    RequestParams params = new RequestParams(url);
    params.addParameter("username","zxw");
    x.http().request(HttpMethod.PUT, params, new Callback.CommonCallback() {
        @Override
        public void onSuccess(String result) {
        }
        @Override
        public void onError(Throwable ex, boolean isOnCallback) {
        }
        @Override
        public void onCancelled(CancelledException cex) {
        }
        @Override
        public void onFinished() {
        }
    });

4.文件上传。

上传文件使用POST请求。

下面给出一个请求事例,代码如下,

       String path="/mnt/sdcard/test.jpg";//文件路径
       RequestParams params = new RequestParams(url);
       params.setMultipart(true);//开启multipart表单 
       params.addBodyParameter("file",new File(path));
       x.http().post(params, new Callback.CommonCallback() {
        @Override
        public void onSuccess(String result) {
        }
        @Override
        public void onError(Throwable ex, boolean isOnCallback) {
        }
        @Override
        public void onCancelled(CancelledException cex) {
        }
        @Override
        public void onFinished() {
        }
        });

上传文件,是以multipart表单的形式,这和在网页上上传文件的原理是一样的!

上传文件是不是很简单呢!

5.文件下载。

首先看看一个回调接口,Callback.ProgressCallback,该接口提供了7个回调方法,

    new Callback.ProgressCallback<String>() {
            @Override
            public void onWaiting() {

            }
              //请求开始的时候回调
            @Override
            public void onStarted() {

            }
             //下载的时候不断回调的方法
            @Override
            public void onLoading(long total, long current, boolean isDownloading) {

            }
             //成功后回调
            @Override
            public void onSuccess(String result) {

            }
             //发生异常时回调
            @Override
            public void onError(Throwable ex, boolean isOnCallback) { 

            }
            //请求取消时回调
            @Override
            public void onCancelled(CancelledException cex) { 

            }
            //请求完成时回调
            @Override
            public void onFinished() { 

            } }

该回调方法已经提供了下载进度这样的方法,便于我们显示进度。

照例,给出一个使用事例代码,如下所示,

    RequestParams params = new RequestParams(url);//url 文件下载路径
    //自定义保存路径,Environment.getExternalStorageDirectory():SD卡的根目录
    params.setSaveFilePath(Environment.getExternalStorageDirectory()+"/download/");
    //自动为文件命名
    params.setAutoRename(true);
    x.http().post(params, new Callback.ProgressCallback<String>() {
            @Override
            public void onWaiting() {

            }
              //请求开始的时候回调
            @Override
            public void onStarted() {

            }
             //下载的时候不断回调的方法
            @Override
            public void onLoading(long total, long current, boolean isDownloading) {

            }
             //成功后回调
            @Override
            public void onSuccess(String result) {

            }
             //发生异常时回调
            @Override
            public void onError(Throwable ex, boolean isOnCallback) {

            }
             //请求取消时回调
            @Override
            public void onCancelled(CancelledException cex) {

            }
             //请求完成时回调
            @Override
            public void onFinished() {

            }
        });

定义了下载文件的保存路径,也可以不指定,使用默认的下载路径;并且可以获取文件的名字,为新下载文件命名。

6.缓存的请求。

还是需要介绍一个回调接口,Callback.CacheCallback,该接口有5个回调方法,

new Callback.CacheCallback<String>() {

	private boolean hasError = false;
	private String result = null;

	@Override
	public boolean onCache(String result) {
		// 得到缓存数据, 缓存过期后不会进入这个方法.
		// 如果服务端没有返回过期时间, 参考params.setCacheMaxAge(maxAge)方法.
        //
        // * 客户端会根据服务端返回的 header 中 max-age 或 expires 来确定本地缓存是否给 onCache 方法.
        //   如果服务端没有返回 max-age 或 expires, 那么缓存将一直保存, 除非这里自己定义了返回false的
        //   逻辑, 那么xUtils将请求新数据, 来覆盖它.
        //
        // * 如果信任该缓存返回 true, 将不再请求网络;
        //   返回 false 继续请求网络, 但会在请求头中加上ETag, Last-Modified等信息,
        //   如果服务端返回304, 则表示数据没有更新, 不继续加载数据.
        //
        this.result = result;
        return false; // true: 信任缓存数据, 不在发起网络请求; false不信任缓存数据.
	}

	@Override
	public void onSuccess(String result) {
		// 注意: 如果服务返回304 或 onCache 选择了信任缓存, 这时result为null.
        if (result != null) {
		    this.result = result;
		}
	}

	@Override
	public void onError(Throwable ex, boolean isOnCallback) {
		hasError = true;
		Toast.makeText(x.app(), ex.getMessage(), Toast.LENGTH_LONG).show();
		if (ex instanceof HttpException) { // 网络错误
			HttpException httpEx = (HttpException) ex;
			int responseCode = httpEx.getCode();
			String responseMsg = httpEx.getMessage();
			String errorResult = httpEx.getResult();
			// ...
		} else { // 其他错误
			// ...
		}
	}

	@Override
	public void onCancelled(CancelledException cex) {
		Toast.makeText(x.app(), "cancelled", Toast.LENGTH_LONG).show();
	}

	@Override
	public void onFinished() {
		if (!hasError && result != null) {
			// 成功获取数据
			Toast.makeText(x.app(), result, Toast.LENGTH_LONG).show();
		}
	}
}

主要看看onCache(String result)方法,在setCacheMaxAge设置范围(上面设置的是60秒)内,如果再次调用GET请求,则会调用,

	@Override
	public boolean onCache(String result) {

        this.result = result;
        return false; // true: 信任缓存数据, 不在发起网络请求; false不信任缓存数据.
	}

返回true:缓存内容被返回,相信本地缓存,返回false:缓存内容被返回,不相信本地缓存,仍然会请求网络

带有缓存的请求示例:

BaiduParams params = new BaiduParams();
params.wd = "xUtils";
// 默认缓存存活时间, 单位:毫秒.(如果服务没有返回有效的max-age或Expires)
params.setCacheMaxAge(1000 * 60);
Callback.Cancelable cancelable
    	// 使用CacheCallback, xUtils将为该请求缓存数据.
		= x.http().get(params, new Callback.CacheCallback<String>() {

	private boolean hasError = false;
	private String result = null;

	@Override
	public boolean onCache(String result) {
		// 得到缓存数据, 缓存过期后不会进入这个方法.
		// 如果服务端没有返回过期时间, 参考params.setCacheMaxAge(maxAge)方法.
        //
        // * 客户端会根据服务端返回的 header 中 max-age 或 expires 来确定本地缓存是否给 onCache 方法.
        //   如果服务端没有返回 max-age 或 expires, 那么缓存将一直保存, 除非这里自己定义了返回false的
        //   逻辑, 那么xUtils将请求新数据, 来覆盖它.
        //
        // * 如果信任该缓存返回 true, 将不再请求网络;
        //   返回 false 继续请求网络, 但会在请求头中加上ETag, Last-Modified等信息,
        //   如果服务端返回304, 则表示数据没有更新, 不继续加载数据.
        //
        this.result = result;
        return false; // true: 信任缓存数据, 不在发起网络请求; false不信任缓存数据.
	}

	@Override
	public void onSuccess(String result) {
		// 注意: 如果服务返回304 或 onCache 选择了信任缓存, 这时result为null.
        if (result != null) {
		    this.result = result;
		}
	}

	@Override
	public void onError(Throwable ex, boolean isOnCallback) {
		hasError = true;
		Toast.makeText(x.app(), ex.getMessage(), Toast.LENGTH_LONG).show();
		if (ex instanceof HttpException) { // 网络错误
			HttpException httpEx = (HttpException) ex;
			int responseCode = httpEx.getCode();
			String responseMsg = httpEx.getMessage();
			String errorResult = httpEx.getResult();
			// ...
		} else { // 其他错误
			// ...
		}
	}

	@Override
	public void onCancelled(CancelledException cex) {
		Toast.makeText(x.app(), "cancelled", Toast.LENGTH_LONG).show();
	}

	@Override
	public void onFinished() {
		if (!hasError && result != null) {
			// 成功获取数据
			Toast.makeText(x.app(), result, Toast.LENGTH_LONG).show();
		}
	}
});

以上就是xUtils框架提供的网络请求方法。总体感觉,确实很方便!有关xUtils框架的使用就到这里!如果还想了解更多,可以去xUtils的github上看它们的sample。

时间: 2024-10-15 03:14:56

xUtils使用详解(二)的相关文章

UINavigationController详解二(转)页面切换和SegmentedController

原文出自:http://blog.csdn.net/totogo2010/article/details/7682433,非常感谢. 1.RootView 跳到SecondView 首先我们需要新一个View.新建SecondView,按住Command键然后按N,弹出新建页面,我们新建SecondView 2.为Button 添加点击事件,实现跳转 在RootViewController.xib中和RootViewController.h文件建立连接 在RootViewController.m

Android 布局学习之——Layout(布局)详解二(常见布局和布局参数)

[Android布局学习系列]   1.Android 布局学习之——Layout(布局)详解一   2.Android 布局学习之——Layout(布局)详解二(常见布局和布局参数)   3.Android 布局学习之——LinearLayout的layout_weight属性   4.Android 布局学习之——LinearLayout属性baselineAligned的作用及baseline    Layout Parameters(布局参数): 在XML文件中,我们经常看到类似与lay

CSS3中的弹性流体盒模型技术详解(二)

在上一篇文章<CSS3中的弹性流体盒模型技术详解(一)>里,我给大家列出了,从css1到css3各版本中盒子模型的基本元素.本篇我会把余下的属性进行详细讲解. box-pack 作用:用来规定子元素在盒子内的水平空间分配方式 box-pack 语法:box-pack: start | end | center | justify; start 对于正常方向的框,首个子元素的左边缘吸附在盒子的左边框显示 对于相反方向的框,最后子元素的右边缘吸附在盒子的右边框显示 end 对于正常方向的框,最后子

php学习之道:WSDL详解(二)

3.定义服务使用的逻辑消息 当服务的操作被调用时,服务被定义为消息交换.在wsdl文档中,这些消息被定义message元素.这些消息由称之为part元素的部分组成. 一个服务的操作,通过指定逻辑消息的方式来定义.当操作被调用时,逻辑消息被交换.(也就是说,逻辑消息代表了服务的操作)这些逻辑消息,将在网络上传输的数据定义为xml文档.他包含了所有的参数,这些参数是方法调用的一部分.(也就是说,逻辑消息里的参数,是操作对应方法的参数集合) 消息和参数列表:每一个被服务暴露的操作能且仅能有一个输入消息

LinearLayout详解二:从其父类View说起

这个View类说来就话长了,但我们又不得不说,要说呢,就得说的彻底,要让大家看得一清二楚,明明白白.所以我们就从源代码角度来看一个view是如何被加载的吧. 如果大家不知道怎么下载android的源代码,或者说懒得去下载(因为源代码确实比较大,大概有10G)的话,教大家几个取巧的办法: 1.直接在google中输入"android view.java"即可.这种方法成功率非常高,一般android的比较重要的类都能搜到. 2.给大家提供一个人家用于放源码的的git:[email pro

jquery validate 详解二

原文:http://blog.sina.com.cn/s/blog_608475eb0100h3h2.html 这里只是第二篇,前面的内容请参阅上一篇 五.常用方法及注意问题 1.用其他方式替代默认的SUBMIT 1 $().ready(function() { 2 $("#signupForm").validate({ 3 submitHandler:function(form){ 4 alert("submitted"); 5 form.submit(); 6

cocos2dx 启动过程详解二:内存管理和回调

在上一篇的第二部分中,我们有一句代码待解释的: // Draw the Scene void CCDirector::drawScene(void) { -- //tick before glClear: issue #533 if (! m_bPaused) //暂停 { m_pScheduler->update(m_fDeltaTime);   //待会会解释这里的内容 } -- } 这里是一个update函数,经常会写像this->schedule(schedule_selector(X

PopUpWindow使用详解(二)——进阶及答疑

相关文章:1.<PopUpWindow使用详解(一)——基本使用>2.<PopUpWindow使用详解(二)——进阶及答疑> 上篇为大家基本讲述了有关PopupWindow的基本使用,但还有几个相关函数还没有讲述,我们这篇将着重看看这几个函数的用法并结合源码来讲讲具体原因,最后是有关PopupWindow在使用时的疑问,给大家讲解一下. 一.常用函数讲解 这段将会给大家讲下下面几个函数的意义及用法,使用上篇那个带背景的例子为基础. [java] view plain copy pu

HTTPS详解二:SSL / TLS 工作原理和详细握手过程

HTTPS 详解一:附带最精美详尽的 HTTPS 原理图 HTTPS详解二:SSL / TLS 工作原理和详细握手过程 在上篇文章HTTPS详解一中,我已经为大家介绍了 HTTPS 的详细原理和通信流程,但总感觉少了点什么,应该是少了对安全层的针对性介绍,那么这篇文章就算是对HTTPS 详解一的补充吧.还记得这张图吧. HTTPS 和 HTTP的区别 显然,HTTPS 相比 HTTP最大的不同就是多了一层 SSL (Secure Sockets Layer 安全套接层)或 TLS (Transp