Volley,小并发网络请求的好帮手

不得不说,当不了解一件事情的时候,就会像当然的认为,其很神秘。但是当真正的接触到了这些神秘的item,就不会有这种感觉了。作为一个android开发新手的我,刚接触到了Volley这个开源的网络请求框架,就瞬间被她打动了。下面我就谈一谈我对Volley的一些理解。


Volley是什么?

Volley是谷歌在2013年的I/O大会上发布的一个网络请求的框架,Volley在性能方面进行了大幅度的调整,它的设计目标就是非常适合去进行数据量不大,但通信频繁的网络操作,而对于大数据量的网络操作,比如说下载文件等,Volley的表现就会非常糟糕。其模型如图所示。

Volley怎么用?

说到了Volley的使用方法,我们就需要先了解一下这个框架的实现业务的流程了,如下:

然后就是了解一下API中相关的常用的几个类及其用法了。

  • Volley:Volley 对外暴露的 API,通过 newRequestQueue(…) 函数新建并启动一个请求队列RequestQueue。
  • Request:表示一个请求的抽象类。StringRequest、JsonRequest、ImageRequest都是它的子类,表示某种类型的请求。
  • RequestQueue:表示请求队列,里面包含一个CacheDispatcher(用于处理走缓存请求的调度线程)、NetworkDispatcher数组(用于处理走网络请求的调度线程),一个ResponseDelivery(返回结果分发接口),通过 start() 函数启动时会启动CacheDispatcher和NetworkDispatchers。
    CacheDispatcher:一个线程,用于调度处理走缓存的请求。启动后会不断从缓存请求队列中取请求处理,队列为空则等待,请求处理结束则将结果传递给ResponseDelivery去执行后续处理。当结果未缓存过、缓存失效或缓存需要刷新的情况下,该请求都需要重新进NetworkDispatcher去调度处理。
  • NetworkDispatcher:一个线程,用于调度处理走网络的请求。启动后会不断从网络请求队列中取请求处理,队列为空则等待,请求处理结束则将结果传递给ResponseDelivery去执行后续处理,并判断结果是否要进行缓存。
  • ResponseDelivery:返回结果分发接口,目前只有基于ExecutorDelivery的在入参 handler 对应线程内进行分发。
  • HttpStack:处理 Http 请求,返回请求结果。目前 Volley 中有基于 HttpURLConnection 的HurlStack和 基于 Apache HttpClient 的HttpClientStack。
  • Network:调用HttpStack处理请求,并将结果转换为可被ResponseDelivery处理的NetworkResponse。
    Cache:缓存请求结果,Volley 默认使用的是基于 sdcard 的
  • DiskBasedCache。NetworkDispatcher得到请求结果后判断是否需要存储在 Cache,CacheDispatcher会从 Cache 中取缓存结果。

好了该知道的我们也差不多都知道了,下面就来一个小例子实际的体验一把吧。

我的Volley小例子

我要完成的是点击一个按钮,然后在下边的两个ImageView上显示一张图片。那么,开始吧。
首先我们要做的就是在我们新建的工程的libs目录下导入需要的Volley.jar包。然后并把其classpath导入。
然后就是设计布局,完善业务逻辑代码。请看下面的详细的解释。

首先是布局文件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <Button
        android:id="@+id/btn_getimage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_marginTop="24dp"
        android:onClick="setImageTo"
        android:text="GetImage" />
    <ImageView
        android:id="@+id/imageview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/btn_getimage"
        android:layout_centerInParent="true"
        android:layout_marginTop="7dp"
        android:visibility="invisible"
        android:src="@drawable/ic_launcher"
        />

    <com.android.volley.toolbox.NetworkImageView
        android:id="@+id/network_image_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/imageview"
        android:layout_centerInParent="true"
        android:layout_gravity="center_horizontal"
        android:src="@drawable/error"
        />  

</RelativeLayout>

然后是Java代码:

package com.guoribiao.volleytest;

import android.app.Activity;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.v4.util.LruCache;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.ImageLoader.ImageCache;
import com.android.volley.toolbox.ImageLoader.ImageListener;
import com.android.volley.toolbox.NetworkImageView;
import com.android.volley.toolbox.Volley;

public class MainActivity extends Activity {

    private Button mButton;
    private ImageView mImageview;
    private NetworkImageView networkImageView;

    public void initView() {
        mButton = (Button) findViewById(R.id.btn_getimage);
        mImageview = (ImageView) findViewById(R.id.imageview);
        networkImageView = (NetworkImageView) findViewById(R.id.network_image_view);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    public void setImageTo(View view ){
        setImage();
        setImageByNetworkImageView();
    }

    /**
     * 使用volley自带的一个网络图片控件实现网络图片的加载
     */
    private void setImageByNetworkImageView() {
        //设置网络请求的图片的URL地址
        String requestUrl = "https://ss0.bdstatic.com/94oJfD_bAAcT8t7mm9GUKT-xh_/timg?image&quality=100&size=b4000_4000&sec=1461212709&di=978a557d108c531a9f76f225454d0c5b&src=http://img5.duitang.com/uploads/item/201509/10/20150910195025_uaSzx.jpeg";
        //创建一个请求队列
        RequestQueue queue = Volley.newRequestQueue(this);
        //使用缓存机制缓存图片
        final LruCache<String , Bitmap> lruCache = new LruCache<String, Bitmap>(20);
        //借助于上面的lrucache实现ImageCache的设置
        ImageCache imageCache = new ImageCache(){
            @Override
            public Bitmap getBitmap(String url) {
                lruCache.get(url);
                return null;
            }
            @Override
            public void putBitmap(String url, Bitmap bitmap) {
                lruCache.put(url, bitmap);
            }
        };
        //创建一个图片加载器
        ImageLoader imageLoader = new ImageLoader(queue,imageCache);
        //给控件设置标签
        networkImageView.setTag("url");
        //设置将要显示的图片的URL和图片加载器
        networkImageView.setImageUrl(requestUrl, imageLoader);
    }

    /**
     * 借助于Volley加载网络上的一张图片到一个ImageView控件上
     */
    private void setImage() {
        //将ImageView设置为可见的状态
        mImageview.setVisibility(1);
        //设置一个请求队列
        RequestQueue queue = Volley.newRequestQueue(this);
        //设置图片所在的URL的地址
        String imageUrl = "http://www.baidu.com/img/bd_logo1.png";
        //设置一个lrucache
        final LruCache< String , Bitmap > cache = new LruCache<String, Bitmap>(20);
        //生成一个图片缓存器
        ImageCache imageCache = new ImageCache(){

            @Override
            public Bitmap getBitmap(String url) {
                cache.get(url);
                return null;
            }
            @Override
            public void putBitmap(String url, Bitmap bitmap) {
                cache.put(url, bitmap);
            }
        };

        //初始化一个图片加载器
        ImageLoader imageLoader = new ImageLoader(queue,imageCache);
        //设置图片加载过程中的一个侦听,并添加到要进行显示的控件上
        ImageListener listener = ImageLoader.getImageListener(mImageview, R.drawable.ic_launcher, R.drawable.error);
        //设置加载的URL地址和监听器
        imageLoader.get(imageUrl, listener);
    }

}

最后,别忘了在manifest.xml清单文件中声明一下网络权限。

<uses-permission android:name="android.permission.INTERNET"/>

最后来看一下测试的结果吧。


而且,当我们刚点击按钮的时候会发现,上面的那个ImageView控件会显示一个默认的ic_launcher图标.这是因为它刚刚正在加载。加载完成后,就会显示正常的网络图片了。

总结

使用Volley的话,适合于那些小流量,请求次数频繁的网络请求,不适合于大数据的下载,所以我们需要按照自己的需求来选择使用。

改进的方向:
别人的,虽然好用,但是不是最适合自己的。我们可以在Volley的基础上,创建自己的网络请求资源代码库,比如说将特殊需求的网络请求进行二次封装,这样可以省去很多时间编写重复性的代码。还能有效的处理。何乐而不为呢。

时间: 2024-10-06 02:20:39

Volley,小并发网络请求的好帮手的相关文章

Android 开源项目推荐之「网络请求哪家强」

网络请求这个话题基本是所有 App 开发都会遇到的,这也难怪之前很多人留言让我写写网络请求到底该怎么选择,今天就来说说网络请求到底哪家强! 1 原则 本篇说的网络请求专指 http 请求,在选择一个框架之前,我个人有个习惯,就是我喜欢选择专注的库,其实在软件设计领域有一个原则叫做 「单一职责原则」,跟我所说的「专注」不谋而合,一个库能把一件事做好就很不错了.现如今有很多大而全的库,比如这个库可以网络请求,同时又可以图片加载,又可以数据存储,又可以 View 注解等等,我们使用这种库当然方便了,但

Android开发中使用Volley库发送HTTP请求的实例教程_Android

Android Volley 是Google开发的一个网络lib,可以让你更加简单并且快速的访问网络数据.Volley库的网络请求都是异步的,你不必担心异步处理问题. Volley的优点: 请求队列和请求优先级 请求Cache和内存管理 扩展性性强 可以取消请求 下载和编译volley.jar需要安装git,ant,android sdk clone代码: git clone https://android.googlesource.com/platform/frameworks/volley

Android开发中使用Volley库发送HTTP请求的实例教程

Android Volley 是Google开发的一个网络lib,可以让你更加简单并且快速的访问网络数据.Volley库的网络请求都是异步的,你不必担心异步处理问题. Volley的优点: 请求队列和请求优先级 请求Cache和内存管理 扩展性性强 可以取消请求 下载和编译volley.jar 需要安装git,ant,android sdk clone代码: git clone https://android.googlesource.com/platform/frameworks/volley

android 网络请求库volley方法详解_Android

使用volley进行网络请求:需先将volley包导入androidstudio中 File下的Project Structrue,点加号导包   volley网络请求步骤:       1. 创建请求队列       RequestQueue queue = Volley.newRequestQueue(this);       2.创建请求对象(3种)                            StringRequest request = new StringRequest("

反编译-android proguard混淆时,不出错,但是网络请求加载的数据不出来,我用的是volley

问题描述 android proguard混淆时,不出错,但是网络请求加载的数据不出来,我用的是volley 我反编译代码看是请求的方法被拆分成了好几个类,可能是这个问题么?但是不知道怎么解决,感激不尽 解决方案 网络请求的三方jar包不能混淆

Android 中Volley二次封装并实现网络请求缓存

Android 中Volley二次封装并实现网络请求缓存 Android目前很多同学使用Volley请求网络数据,但是Volley没有对请求过得数据进行缓存,因此需要我们自己手动缓存. 一下就是我的一种思路,仅供参考 具体使用方法为: HashMap<String,String> params = new HashMap<>(); params.put("id", "1"); params.put("user", &quo

Android 网络请求框架Volley实例详解

Android 网络请求框架Volley实例详解 首先上效果图 Logcat日志信息on Reponse Volley特别适合数据量不大但是通信频繁的场景,像文件上传下载不适合! 首先第一步 用到的RequetQueue RequestQueue.Java RequestQueue请求队列首先得先说一下,ReuqestQueue是如何对请求进行管理的...RequestQueue是对所有的请求进行保存...然后通过自身的start()方法开启一个CacheDispatcher线程用于缓存调度,开

android 网络请求库volley方法详解

使用volley进行网络请求:需先将volley包导入androidstudio中 File下的Project Structrue,点加号导包 volley网络请求步骤: 1. 创建请求队列       RequestQueue queue = Volley.newRequestQueue(this); 2.创建请求对象(3种) StringRequest request = new StringRequest("请求方法","请求的网络地址","成功的网

Android 网络请求详解

我们知道大多数的 Android 应用程序都是通过和服务器进行交互来获取数据的.如果使用 HTTP 协议来发送和接收网络数据,就免不了使用 HttpURLConnection 和 HttpClient,而 Android 中主要提供了上述两种方式来进行 HTTP 操作.并且这两种方式都支持 HTTPS 协议.以流的形式进行上传和下载.配置超时时间.IPv6.以及连接池等功能. 但是 Googl e发布 6.0 版本的时候声明原生剔除 HttpClient,但是笔者认为 HttpClient 会提