Android中关于Volley的使用(十)对Request和Reponse的认识

OkHttp3源码详解(一) Request类,2021年Android开发实战 HttpUrl主要用来规范普通的url连接,并且解析url的组成部分 现通过下面的例子来示例httpUrl的使用 https://www.google.com/search?q=maplejaw ①使用parse解析url字符串: HttpUrl url = HttpUrl.parse(“https://www.google.com/search?q=maplejaw”); ②通过构造者模式来常见: HttpUrl url = new HttpUrl.Builder() .scheme(“ 阅读详情

我们知道,在网络Http通信中,一定会有一个Request,同样的,也一定会有一个Response,而我们在Volley中利用RequestQueue来添加请求之前,一定会先创建一个Request对象,比如StringRequest,JsonObjectRequest和ImageRequest等,如下分别是前面Demo中的JsonRequest和ImageRequest:

JsonObjectRequest:

    public JsonObjectRequest(String url, JSONObject jsonRequest, Listener<JSONObject> listener,
            ErrorListener errorListener) {

ImageRequest:

    public ImageRequest(String url, Response.Listener<Bitmap> listener, int maxWidth, int maxHeight,
            Config decodeConfig, Response.ErrorListener errorListener) 

Volley中提供了一个基础的Request抽象类,如下:

public abstract class Request<T> implements Comparable<Request<T>> {

在这个类中,定义了一些请求中基本的参数变量,如

Method:

    /**
     * Request method of this request.  Currently supports GET, POST, PUT, DELETE, HEAD, OPTIONS,
     * TRACE, and PATCH.
     */
    private final int mMethod;
它的值如下:

    /**
     * Supported request methods.
     */
    public interface Method {
        int DEPRECATED_GET_OR_POST = -1;
        int GET = 0;
        int POST = 1;
        int PUT = 2;
        int DELETE = 3;
        int HEAD = 4;
        int OPTIONS = 5;
        int TRACE = 6;
        int PATCH = 7;
    }

请求中的Url:

    /** URL of this request. */
    private final String mUrl;

一个ErroListener,

    /** Listener interface for errors. */
    private final Response.ErrorListener mErrorListener;

还有其它的一些参数,如shouldCache(是否需要缓存),tag(分类标签)等,而在Request中还提供了下面两个抽象方法,必须由子类实现:

    /**
     * Subclasses must implement this to parse the raw network response
     * and return an appropriate response type. This method will be
     * called from a worker thread.  The response will not be delivered
     * if you return null.
     * @param response Response from the network
     * @return The parsed response, or null in the case of an error
     */
    abstract protected Response<T> parseNetworkResponse(NetworkResponse response);

    /**
     * Subclasses must implement this to perform delivery of the parsed
     * response to their listeners.  The given response is guaranteed to
     * be non-null; responses that fail to parse are not delivered.
     * @param response The parsed response returned by
     * {@link #parseNetworkResponse(NetworkResponse)}
     */
    abstract protected void deliverResponse(T response);

每一个子类都必须实现两个方法,

1)parseNetworkResponse

当从网络中获取到Response的时候,怎么去解析对应的请求,这是由各个对应的Request去分析的,比如JsonObjectRequest中:

    @Override
    protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
        try {
            String jsonString =
                new String(response.data, HttpHeaderParser.parseCharset(response.headers));
            return Response.success(new JSONObject(jsonString),
                    HttpHeaderParser.parseCacheHeaders(response));
        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        } catch (JSONException je) {
            return Response.error(new ParseError(je));
        }
    }

再比如ImageRequest中的:

    @Override
    protected Response<Bitmap> parseNetworkResponse(NetworkResponse response) {
        // Serialize all decode on a global lock to reduce concurrent heap usage.
        synchronized (sDecodeLock) {
            try {
                return doParse(response);
            } catch (OutOfMemoryError e) {
                VolleyLog.e("Caught OOM for %d byte image, url=%s", response.data.length, getUrl());
                return Response.error(new ParseError(e));
            }
        }
    }

而在doParse中,其实是对图片进行处理,如下:

    private Response<Bitmap> doParse(NetworkResponse response) {
        byte[] data = response.data;
        BitmapFactory.Options decodeOptions = new BitmapFactory.Options();
        Bitmap bitmap = null;
        if (mMaxWidth == 0 && mMaxHeight == 0) {
            decodeOptions.inPreferredConfig = mDecodeConfig;
            bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, decodeOptions);
        } else {
            // If we have to resize this image, first get the natural bounds.
            decodeOptions.inJustDecodeBounds = true;
            BitmapFactory.decodeByteArray(data, 0, data.length, decodeOptions);
            int actualWidth = decodeOptions.outWidth;
            int actualHeight = decodeOptions.outHeight;

            // Then compute the dimensions we would ideally like to decode to.
            int desiredWidth = getResizedDimension(mMaxWidth, mMaxHeight,
                    actualWidth, actualHeight);
            int desiredHeight = getResizedDimension(mMaxHeight, mMaxWidth,
                    actualHeight, actualWidth);

            // Decode to the nearest power of two scaling factor.
            decodeOptions.inJustDecodeBounds = false;
            // TODO(ficus): Do we need this or is it okay since API 8 doesn't support it?
            // decodeOptions.inPreferQualityOverSpeed = PREFER_QUALITY_OVER_SPEED;
            decodeOptions.inSampleSize =
                findBestSampleSize(actualWidth, actualHeight, desiredWidth, desiredHeight);
            Bitmap tempBitmap =
                BitmapFactory.decodeByteArray(data, 0, data.length, decodeOptions);

            // If necessary, scale down to the maximal acceptable size.
            if (tempBitmap != null && (tempBitmap.getWidth() > desiredWidth ||
                    tempBitmap.getHeight() > desiredHeight)) {
                bitmap = Bitmap.createScaledBitmap(tempBitmap,
                        desiredWidth, desiredHeight, true);
                tempBitmap.recycle();
            } else {
                bitmap = tempBitmap;
            }
        }

        if (bitmap == null) {
            return Response.error(new ParseError(response));
        } else {
            return Response.success(bitmap, HttpHeaderParser.parseCacheHeaders(response));
        }
    }

所以,如果我们自定义一个Request的话,我们就要去实现我们自己的逻辑,比如是获取视频的话,就会去对数据进行解码等。

在上面的方法实现中,我们可以看到,最后都是通过Response.success方法返回一个Response对象,而这个Response对象是怎么用的呢,就要看下面deliverResponse方法了。

2)deliverResponse

在NetworkDispatcher线程中,当从网络中获取到数据,并通过请求的parseNetworkResponse方法解析之后,会返回一个Reponse对象,这个时候,就会调用Executor来将这个请求post回主线程,如下:

mDelivery.postResponse(request, response);

而mDelivery中的postResponse方法其实是另起一个新线程来调用Request的deliverResponse方法,在ExecutorDelivery类中:

public void postResponse(Request<?> request, Response<?> response, Runnable runnable) {
        request.markDelivered();
        request.addMarker("post-response");
        mResponsePoster.execute(new ResponseDeliveryRunnable(request, response, runnable));
    }

ResponseDeliveryRunnable类的run方法中,我们可以看到:

            // Deliver a normal response or error, depending.
            if (mResponse.isSuccess()) {
                mRequest.deliverResponse(mResponse.result);
            } else {
                mRequest.deliverError(mResponse.error);
            }

那我们看看StringRequest和ImageRequest中的deliverResponse方法:

private final Response.Listener<Bitmap> mListener;
...
@Override
    protected void deliverResponse(Bitmap response) {
        mListener.onResponse(response);
    }
我们可以看到,其实都是调用一个Response.Listener类的onResponse方法,而其实这个Listener,则是我们在创建请求的时候才实现,并传进来的,如前面Demo中创建JsonObjectRequest和ImageRequest的时候:

ImageRequest imgRequest = new ImageRequest(imgUrl,
				new Response.Listener<Bitmap>() {
					@Override
					public void onResponse(Bitmap arg0) {
						// TODO Auto-generated method stub
						imageView.setImageBitmap(arg0);
					}
				}, 
				100, 
				100, 
				Config.ARGB_8888, 
				new ErrorListener() {
					@Override
					public void onErrorResponse(VolleyError arg0) {
						imageView.setImageResource(R.drawable.ic_launcher);
					}
				});

如上面new Reponse.Listener方法中的实现,很显然,之所以这么做的原因在于只有调用者才知道怎么去处理Request解析过的数据。

而从这里,我们也可以知道在Reponse类中,就会定义这么一个接口,如下,是Volley中Response类的定义:

public class Response<T> {

    /** Callback interface for delivering parsed responses. */
    public interface Listener<T> {
        /** Called when a response is received. */
        public void onResponse(T response);
    }

而除了这个接口的定义,还有一个ErrorListener接口的定义就不列出来了。而除此之外,Response类中就存放了CacheEntry等信息,相对来说,因为定义了这样的Listener接口,Response类是相对比较简单的。

好了,到这里,总结一下:

1)创建一个Request的时候,会同时设置一个Response.Listener作为请求的一个参数变量,之后调用RequestQueue的add方法将其添加到Queue。

2)在Queue中的请求会由NetworkDispatcher去跟网络进行通信(如果有缓存的时候,就是CacheDispatcher)。

3)当请求结果回来的时候,Request会首先调用parseNetworkResponse方法根据不同的请求类型,如Json,Image等进行不同的处理。

4)当Request分析完之后,得到的Reponse对象,就会由ResponseDelivery类新起一个线程,调用1)步中的Listener来进行处理。

结束。


Android Request Response初级用法样例-源代码.rar 相对较基础的android基础实例,演示Android Request Response的初级用法,附带本样例源代码,在WEB开发中, Request Response也是很重要的两个方法,在Android开发中,同样重要,也很基础,这个例子就是教会android新手如何使用好Request和Response,这在android程序设计中很有必要。 立即下载

相关推荐

ComfyUI安装包运行前准备:安装Git

Git 是一个分布式版本控制系统(Version Control System, VCS),用于跟踪和管理文件(尤其是代码)的变更历史。 简单理解就是,git是用来管理文件的版本的,如果有新的版本,就可以使用git来更新。

聚梦小课堂 2万+

Android开发——Volley的使用详解

0. 前言 Android系统中主要提供了HttpURLConnection和HttpClient进行网络通信,但是如果不对其进行封装就很容易就会写出重复代码。因此一些Android网络通信框架应运而生, Volley就是其中的佼佼者,Volley不仅可以进行HTTP通信,也可以轻松加载网络上的图片。Volley设计的初衷就是非常适合去进行数据量不大,但通信频繁的网络操作,而对于大数据量的网络操......

关于Android开发的一些技术点总结 ╮( ̄▽ ̄”)╭ 4079

Windows Server 域控搭建:AD DS 规划、部署与排障实战

活动目录(AD DS)是 Windows Server 中用于集中管理账号、计算机与策略的核心目录服务,其底层依赖 DNS、Kerberos 和 LDAP 完成身份认证与资源定位。通过域控制器统一身份、组策略和权限边界,企业可显著降低多机环境下账号维护、权限分配与审计成本。十几到上百台终端、有共享隔离与合规要求的局域网,通常适合部署域控;小规模环境则未必划算。围绕域名规划、DNS 指向、OU 设计、FSMO、备份恢复和常见加域故障,域控搭建与 AD 运维需要兼顾前期规划与长期排障,才能让 Windows S

weixin_33845881的博客 760

java.io.IOException: Server returned HTTP response code: 500 for URL解决办法

今天遇到一个问题,写了一个客户端远程查询数据,结果报错了: java.io.IOException: Server returned HTTP response code: 500 for URL: http://adserver.sinosns.cn/owner/owner_userAndOwner.action 客户端代码如下: 服务器端代码: 结果,因为传递的参数

shen2008biye的专栏 1万+

YooAsset可寻址模式避坑指南:从路径加载到Addressable的完整迁移方案

本文详细介绍了将Unity项目从传统路径加载迁移到YooAsset可寻址模式的完整方案。针对中大型项目在迁移过程中遇到的路径耦合、依赖管理、热更新等痛点,提供了从架构设计、环境配置、代码迁移到性能优化的实战指南,并分享了实际项目的改造案例与避坑经验,帮助团队高效完成资源管理系统的重构。

weixin_28304023的博客 497

强化学习经典算法笔记(九):LSTM加持的PolicyGradient算法

强化学习经典算法笔记(九):LSTM加持的PolicyGradient算法 在上文《强化学习经典算法笔记(八):LSTM加持的A2C算法解决POMDP问题》的基础上,实现了LSTM+MLP的Policy Gradient算法。 实现过程如下: import argparse, math, os, sys import numpy as np import gym from gym import wrappers import matplotlib.pyplot as plt import torch fr

hhy_csdn的博客 5636

教你写Android网络框架之Request、Response类与请求队列

在教你写Android网络框架之基本架构一文中我们已经介绍了SimpleNet网络框架的基本结构,今天我们就开始从代码的角度来开始切入该网络框架的实现,在剖析的同时我们会分析设计思路,以及为什么要这样做,这样做的好处是什么。这样我们不仅学到了如何实现网络框架,也会学到设计一个通用的框架应该有哪些考虑,这就扩展到框架设计的范畴,通过这个简单的实例希望能给新人一些帮助

Mr.Simple的专栏 2万+

【WRF-Urban】使用 NUDAPT 数据集与 BEP/BEP_BEM 方案的 WRF 配置指南

【WRF-Urban】使用 NUDAPT 数据集与 BEP/BEP_BEM 方案的 WRF 配置指南

WW、forever的博客 1964

Android使用request发送数据包,当网络无法连接时,实现数据包自动保存,等网络连接后自动发送。

安卓开发中,实现了题目描述功能。 @Override // 文件上传的请求体封装 MultipartBody multipartBody = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("image", image.getName(), requestBody)

JWQ_优快云的博客 884

【推荐100个unity插件】Unity URP(通用渲染管线)的基于物理的天地和预计算大气散射——UnityPhysicallyBasedSkyURP

本文介绍了Unity URP(通用渲染管线)中基于物理的天地和预计算大气散射的实现方法。该插件提供物理天空、大气散射、高度雾效、动态天空反射和环境光等功能,要求Unity 2022.3及以上版本,支持着色器模型3.5+。使用步骤包括:添加渲染器功能、配置Volume组件(天空、雾效等),并建议太阳强度设为3、曝光为0作为初始设置。插件已在GitHub和Gitee开源,附带详细配置截图和效果展示。文末推荐了多个Unity开发相关专栏,涵盖游戏开发全领域知识。作者向宇提供了博客链接,欢迎交流学习问题。

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 1225

计算机视觉 | 面试题:01、过拟合和欠拟合的表现与解决方法

问题 过拟合和欠拟合的表现和解决方法。 其实除了欠拟合和过拟合,还有一种是适度拟合,适度拟合就是我们模型训练想要达到的状态,不过适度拟合这个词平时真的好少见,在做酷狗音乐的笔试题时还懵逼了一会,居然还真的有这样的说法。 这应该是基础中的基础了,笔试题都做烂了。那就当做今天周末,继续放个假吧…… 过拟合 过拟合的表现 模型在训练集上的表现非常好,但是在测试集、验证集以及新数据上的表现很差,损失曲线呈现一种高方差状态。(高方差指的是训练集误差较低,而测试集误差比训练集大较多) 过拟合的原因 从两个角度去分析

Mrrunsen的博客 866

Android有关Volley使用(十)至Request和Reponse意识

我们知道,。网络Http沟通,会有一个Request,相同,也将有Response。我们Volley在使用RequestQueue来之前加入的请求。我们将创建一个Request对象,例StringRequest。JsonObjectRequest和ImageRequest等。例如以下各自是前面Demo中的JsonRequest和ImageRequest: JsonObjectReques...

weixin_34005042的博客 100

【K8S系列】Kubernetes 中 Service 的流量不均匀问题【已解决】

在 Kubernetes 中,Service 是一种抽象,用于定义一组 Pod 的访问策略。当某些 Pod 接收的流量过多,而其他 Pod 的流量较少时,可能会导致负载不均衡。这种情况不仅影响性能,还可能导致某些 Pod 过载,影响应用的可用性。本文将详细分析此问题的原因及其解决方案。

颜淡慕潇 8737

自学Android开发 关于OkHttp3的request和respond拦截打印Log

在开发Android项目时,一定需要和后端对接网络请求,但在因为现在都JSON格式的数据结构,在数据字段前后不一致是Android端是无法判断是是字段错误还是数据本身没有值。所有在数据还没有被Gson反序列前拦截 回应并打印body 就可以知道后端传过来的知道和值的真实情况。这样就很清楚是Android端的问题还是后端的问题,也可以减少debug的时间。 关于Okhttp3+retrofit2+Rxjava3的具体配置可以参考自学Android开发 我的Retrofit2+RxJava3的封装拦截器代码

一个从事Android开发的平凡工程师 1841

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

服务器响应码500,java.io.IOException:服务器返回的HTTP响应代码:500

我正在用Java面对这个问题。我想从URL获取一些HTML信息。该代码已经运行了很长时间,但是突然,它停止了工作。当我使用浏览器访问此URL时,它毫无问题地打开。代码:URL site = new URL(this.url);java.net.URLConnection yc = site.openConnection();BufferedReader in = new BufferedReade...

weixin_42429956的博客 1832

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Error: Request failed with status code 500的错误

前后端分离的项目中 前端利用post请求给后端发送数据,但是出现了错误: Error: Request failed with status code 500的错误 我们要知道 500代表 (服务器内部错误) 服务器遇到错误,无法完成请求。 看一下我原来的部分代码: 前端请求: 后端接收实体和控制层代码: 这个时候仔细一看 ,会发现我前端在发送请求的时候...

立志欲坚不欲锐,成功在久不在速度 19万+

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

android知识要点整理(14)----Volley(HTTP请求框架)

Volley是一个HTTP库,用于为Android应用提供更见便捷快速的网络请求。Volley有以下特点: - 自动调度网络请求 - 支持并发网络连接 - 屏蔽响应缓存细节 - 支持设置请求的优先级 - 支持取消单个或一组请求 - 容易定制请求 - 网络请求结果按请求顺序返回,这样更加方便控制UI的显示 - 提供调试和跟踪工具 但是,Volley**不适用于下载大文件和处理数据流

zengnianan的专栏 458

安卓常用网络请求框架XUtils、OkHttp、Volley

由于文章篇幅原因,我只把面试题列了出来,详细的答案,我整理成了一份PDF文档,这份文档还包括了还有高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 ,帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习。[外链图片转存中…(img-MHelUvmp-1711999528067)][外链图片转存中…(img-0lyEd8bU-1711999528067)][外链图片转存中…(img-5zio26WZ-1711999528068)]

m0_57473261的博客 1231

Android网络开发学习总结

网络框架对比和源码分析 自己去设计网络请求框架,怎么做? Volley: Android网络框架-Volley okhttp okhttp如何处理网络缓存的:使用CacheControl处理,Request.Builder().cacheControl(cache)。 HttpUrlConnection 和 okhttp关系: HttpUrlConnection 在Android4.4之后,是通过okhttp实现的,用HttpHandler作为桥梁过渡。 其它 WebSocket与...

风和先行的专栏 771

记录解决java.io.IOException: Server returned HTTP response code: 500 for URL:xxxxxxxx

踩坑经历 因为项目需要去对接别的接口,使用URLConnection POST请求https接口,发送json数组时遇到java.io.IOException: Server returned HTTP response code: 500 for URL。 当时情况是本地测试通过,正常返回,放到linux云服务器上测试通过,正常返回,放到windows server服务器上就有问题了,就是上...

真是适合睡觉的天气 4万+
上一篇: Android关于Task的一些实践之SingleTask, SingleInstance和TaskAffinity
下一篇: Android中关于JNI 的学习(零)简单的例子,简单地入门
linmiansheng
博客等级 码龄20年 507粉丝 111原创
评论 13
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值