Android中的Volley框架解析

最近更新了下android studio的版本到1.3.2,API也更新到最新的23,但是在写一个网络请求时遇到了一个问题,那就是HttpClient的API已经完全被擦出了,从此在API23 及以上版本中就不能直接使用HttpClient了,当然如果执意要继续使用,还是有办法的,1.你可以把api降级,这个对于一般人都是无法忍受的,那么还有另一个办法 2.google在sdk里面还给我们留了一个jar包  org.apache.http.legacy.jar,估计也料到有那么一部分极端分子

说到这里,google官方为啥要移除HttpClient呢,原因肯定只有一个,那就是有更好的东西可以替代它,有了新欢,旧爱就不是那么重要了。这个新欢就是Volley框架。

一、为什么是Volley框架呢?

1.避开HttpUrlConnection 和HttpClient

因为HttpUrlConnection 和HttpClient并不是很完美

2.避开AsyncTask框架

自从引入Honeycomb(API 11),系统强制网络操作必须运行在单独的线程中,UI线程之后,每次都还要在另一个线程中处理一些网络的任务,你是不是觉得很是蛋疼

使用AsyncTask,首先你得在onPreExecute做一些准备工作,比如定义context。然后在doInBackground 方法中执行后台任务,最后在onPostExecute中处理结果。这要比实现service更简单直接,因此有大量的例子和文章出现。

但是AsyncTask的主要问题是调用的顺序。你无法决定哪个请求走在最前面,哪个请求必须等待,所有的请求都是按照先进先出的顺序,FIFO。

在某些情况下,问题就出来了,比如当你需要加载一个item中带有图片的列表。当用户向下滚动想获得新的数据时,你无法告诉Activity先加载下一页的json数据,只有慢慢等待上一页的图片加载完。对于像facebook和Twiitter这种item数据的重要性远大于相关图片的应用来说,这会导致严重的用户体验问题。

Volley用其强大的cancellation api解决了这个问题。当调用的时候,你不再需要在onPostExecute中检查Activity是否被销毁。这帮助我们避免了不想要的NullPointerException。


Volley的特点:速度快,可以缓存

在日益提高的用户体验中,速度的要求已经越来越高,特别是针对上网,因为现在的应用基本都会涉及到网络。可以缓存的特点就更不用说了,你有没有想过有一个item的列表 -  假设是JSON 数组 -  并且每个item都包括一段描述和一个缩略图。现在设想一下用户旋转屏幕之后会发生的事情:activity销毁,列表重新加载,同样的还有图片。长话短说就是:严重的资源浪费以及糟糕的用户体验。


二、Volley的内部框架

Volley分为三层,每一层都工作在自己的线程中。下面是一张简图

underthehood.jpg



主线程

在主线程中,你只允许触发请求与处理返回结果,不能多也不能少。

其结果就是你实际上可以忽略在使用AsyncTask的时候doInBackground 方法里面所做的事情。Volley 自动管理http传输同时捕获网络错误,这些都是以前需要我们自己考虑的。

缓存与网络线程

当你向队列中添加了一个请求,背后发生了几件事情。Volley会检查这个请求是否可以从缓存中得到。如果可以,缓存将负责读取,解析,和分发。否则将传递给网络线程。

在网络线程中,一些列的轮询线程不断的在工作。第一个可用的网络线程线程让请求队列出列,发出http请求,解析返回的结果,并写入到缓存中。最后,把解析的结果分发给主线程的listener中。



三、Volley的使用

说了那么多没用的,我们现在进入正题


首先要说一点不太能让人理解的地方,那就是Volley没有官方的Maven repository

第一步、准备好Volley的jar包,如果你电脑上安装有git,那么可以直接用下面的命令来下载Volley的源代码

<span style="font-size:18px;">git clone https://android.googlesource.com/platform/frameworks/volley </span>

下载完后导入到你的工程中,当然如果你电脑上没安装Git的话,可以从直接从网上下载,google一下就有了。可以直接搜别人导好的jar包。

如果你想自己导出jar包也行,具体步骤如下:

将源码作为一个module导入。在Android Studio中,在打开项目的情况下,选择File > New Module,然后选择Import Existing Project。选择你下载的源码的所在目录然后确认。一个名为Volley的文件夹将出现在你的项目结构中。Android Studio会自动的更新settings.gradle文件以包含Volley module,因此你只需添加你的依赖compile project(':volley'),然后就完成了。


第二步、使用

不像HttpUrlConnection 和HttpClient那样复杂,一般Volley只会用到两个类,RequestQueueRequest你首先创建一个RequestQueueRequestQueue管理工作线程并将解析的结果发送给主线程。然后你传递一个或者多个Request RequestQueue是一个请求队列对象,它可以缓存所有的HTTP请求,然后按照一定的算法并发地发出这些请求。RequestQueue内部的设计就是非常合适高并发的,因此我们不必为每一次HTTP请求都创建一个RequestQueue对象,这是非常浪费资源的,基本上在每一个需要和网络交互的Activity中创建一个RequestQueue对象就足够了

Volley实现了三种常见的请求类型:

  • StringRequest

  • ImageRequest

  • JsonRequest

  • 从名字中就可以看出每个类各自的作用了,每个类都是继承自Request类,下面给出一个小例子吧

  • String url = "http://httpbin.org/get?site=code&network=tutsplus";
      
    JsonObjectRequest jsonRequest = new JsonObjectRequest
            (Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {
                    // the response is already constructed as a JSONObject!
                    try {
                        response = response.getJSONObject("args");
                        String site = response.getString("site"),
                                network = response.getString("network");
                        System.out.println("Site: "+site+"\nNetwork: "+network);
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }, new Response.ErrorListener() {
      
                @Override
                public void onErrorResponse(VolleyError error) {
                    error.printStackTrace();
                }
            });
      
    Volley.newRequestQueue(this).add(jsonRequest);


只需要传入相应的参数就可以使用了,其中 new Response.Listener是成功的回掉, Response.ErrorListener是失败的回掉,只需要在里面做出相应的处理就行。


对于post请求

String url = "http://httpbin.org/post";
  
StringRequest postRequest = new StringRequest(Request.Method.POST, url,
        new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                try {
                    JSONObject jsonResponse = new JSONObject(response).getJSONObject("form");
                    String site = jsonResponse.getString("site"),
                            network = jsonResponse.getString("network");
                    System.out.println("Site: "+site+"\nNetwork: "+network);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        },
        new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                error.printStackTrace();
            }
        }
) {
    @Override
    protected Map<String, String> getParams()
    {
        Map<String, String>  params = new HashMap<>();
        // the POST parameters:
        params.put("site", "code");
        params.put("network", "tutsplus");
        return params;
    }
};
Volley.newRequestQueue(this).add(postRequest);

最后是取消一个请求了, 如果你想取消所有的请求,在onStop方法中添加如下代码:

@Override
protected void onStop() {
    super.onStop();
    mRequestQueue.cancelAll(new RequestQueue.RequestFilter() {
        @Override
        public boolean apply(Request<?> request) {
            // do I have to cancel this?
            return true; // -> always yes
        }
    });
}

这样你就不必担心在onResponse被调用的时候用户已经销毁Activity。这种情况下会抛出NullPointerException异。但是post请求则需要继续,即使用户已经改变了Activity。我们可以通过使用tag来做到,在构造GET请求的时候,添加一个tag给它。

// after declaring your request
request.setTag("GET");
mRequestQueue.add(request);


如果要取消GET请求,只需简单的添加下面的一行代码:

mRequestQueue.cancelAll("GET");

这样你就只会取消GET请求,让其它请求不受影响。注意你必须手动在销毁的Activity中处理这种情况。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值