volley源码解析(七)--最终目的之Response<T>

在上篇文章中,我们最终通过网络,获取到了HttpResponse对象

HttpResponse是android包里面的一个类,然后为了更高的扩展性,我们在BasicNetwork类里面看到,Volley将其包装成一个Volley自己的对象NetworkResponse

另外,在BasicNetwork类中我们也注意到,对HttpResponse包装成NetworkResponse的过程中,使用HttpResponse的Inputstream,将数据保存在一个byte[]数组中。

BasicNetwork代码片段:

 // Some responses such as 204s do not have content.  We must check.  
                if (httpResponse.getEntity() != null) {//返回响应主体  
                  responseContents = entityToBytes(httpResponse.getEntity());//将主体转换byte[]形式  
                } else {//没有返回内容  
                  // Add 0 byte response as a way of honestly representing a  
                  // no-content request.  
                  responseContents = new byte[0];  
                }  
这样可能造成的一个问题,就是内存溢出,这也是Volley之所以不能用来下载大文件的原因,因为byte[]是保存在内存中的。


好了,下面让我们来看NetworkResponse的源码

     /** 
     * The HTTP status code.
     * http状态码 
     */
    public final int statusCode;

    /** 
     * Raw data from this response.
     * 数据 
     */
    public final byte[] data;

    /** 
     * Response headers.
     * 响应头 
     */
    public final Map<String, String> headers;

    /** 
     * True if the server returned a 304 (Not Modified).
     * 网页是否修改.304 
     */
    public final boolean notModified;

    /** 
     * Network roundtrip time in milliseconds.
     * 响应时间 
     */
    public final long networkTimeMs;

/**
     * Creates a new network response.
     * @param statusCode the HTTP status code
     * @param data Response body
     * @param headers Headers returned with this response, or null for none
     * @param notModified True if the server returned a 304 and the data was already in cache
     * @param networkTimeMs Round-trip network time to receive network response
     */
    public NetworkResponse(int statusCode, byte[] data, Map<String, String> headers,
            boolean notModified, long networkTimeMs) {
        this.statusCode = statusCode;
        this.data = data;
        this.headers = headers;
        this.notModified = notModified;
        this.networkTimeMs = networkTimeMs;
    }

本质上没有什么特别的,只是将HttpResponse的内容,简单地转移到NetworkResponse中


接下来,在响应分发过程中,request负责把NetworkResponse又包装成Response<T>对象

NetworkDispatcher代码片段:

// Parse the response here on the worker thread. 解析网络响应到本地
                Response<?> response = request.parseNetworkResponse(networkResponse);
至于怎么解析,不同的request应该有自己的实现。


可能看到这里大家有些迷糊,原因是我们找回了之前类的一些代码

在前面的解析中,我们总是忽略这些片段,默认为全都是Response,因为在前面的过程中,理解Response之间的不同会给我们理解核心代码带来困扰,所以我们都跳过了。

现在源码解析接近尾声,我们再回头看各种各样的Response就豁然开朗了。

httpStack获得的是HttpResponse,由于HttpResponse是android的内置类,我们使用起来非常不灵活(因为我们希望response都是一样的,无论是从缓存中取的还是网络请求的)

根据上述原因,我们有了NetworkResponse,这个代表网络请求相应,这是Volley的自定义类,这样我们使用起来就灵活了(理论上缓存也应该有一个CacheResponse,然而Volley没有这样设计)。更加重要的一点是NetworkResponse中的byte[]数组保存了网络数据(前面说过,这是造成内存溢出的原因)

最后,为了统一所有的Response,我们将NetworkResponse(理论上还有一个CacheResponse)又封装成了了Response<T>


OK,Volley解析基本到这里就结束了。接下来的文章,将会带大家看一下Volley最后的一部分小花絮,关于图片加载的部分。

另外,我还会根据自己的理解,带大家来改造Volley,使之有更多更完善的功能。


  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Volley中,当请求成功时,会调用`onResponse`方法,并将服务器返回的数据作为参数传递给该方法。你可以通过以下步骤来获取返回的数据: 1. 在你的Request对象中,覆盖`parseNetworkResponse`方法,将服务器返回的数据转换为你需要的格式。例如,如果服务器返回的是JSON格式的数据,你可以将其转换为JSONObject或者Java对象。 2. 在`parseNetworkResponse`方法中,将转换后的数据传递给`deliverResponse`方法。这个方法会在主线程中执行,并且会调用`onResponse`方法。 3. 在`onResponse`方法中,将获取到的数据进行处理。如果你需要更新UI,你需要在主线程中执行更新操作。 以下是示例代码: ``` public class MyRequest extends Request<MyResponse> { private Response.Listener<MyResponse> mListener; public MyRequest(int method, String url, Response.Listener<MyResponse> listener, Response.ErrorListener errorListener) { super(method, url, errorListener); mListener = listener; } @Override protected Response<MyResponse> parseNetworkResponse(NetworkResponse response) { // 将服务器返回的数据转换为MyResponse对象 MyResponse myResponse = ...; // 返回转换后的数据 return Response.success(myResponse, HttpHeaderParser.parseCacheHeaders(response)); } @Override protected void deliverResponse(MyResponse response) { // 将转换后的数据传递给onResponse方法 mListener.onResponse(response); } } // 发起请求 MyRequest request = new MyRequest(Request.Method.GET, url, new Response.Listener<MyResponse>() { @Override public void onResponse(MyResponse response) { // 获取到数据后进行处理 // 如果需要更新UI,需要在主线程中执行更新操作 } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { // 处理请求错误 } }); Volley.newRequestQueue(context).add(request); ``` 在上面的代码中,`MyResponse`是你自定义的数据类型,用来保存服务器返回的数据。`MyRequest`继承自Volley的`Request`类,用来发送请求和解析服务器返回的数据。在`MyRequest`中,`parseNetworkResponse`方法将服务器返回的数据转换为`MyResponse`对象,并在`deliverResponse`方法中将转换后的数据传递给`onResponse`方法。在`onResponse`方法中,你可以获取到服务器返回的数据,并进行处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值