Android Volley (1)

1. volley的简单介绍

Volley is an HTTP library that makes networking for Android apps easier and most importantly, faster. Volley is available through the open AOSP repository.

Volley 是一个HTTP库。它使得android app的网络数据传输更简单,更快。

Volley的设计目标就是非常适合去进行数据量不大,但通信频繁的网络操作,而对于大数据量的网络操作,比如说下载文件,流视频操作等,Volley的表现就会非常糟糕,我一般考虑DownloadManager。

Volley源码下载地址:

git clone https://android.googlesource.com/platform/frameworks/volley

我们把代码下载下来,参考Android working with Volley Library,我们可以生成volley.jar,我们在项目中,可以直接使用volley.jar包。

2. StringRequest

我们先从最简单的StringRequest开始,介绍一下如何使用Volley去发起string的请求:

public class Lesson01Activity extends Activity {

    public static final String TAG = "Lesson01Activity";
    private StringRequest stringRequest;
    private RequestQueue mRequestQueue;
    private TextView mTextView;

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

    private void init() {
        // TODO Auto-generated method stub
        mTextView = (TextView) findViewById(R.id.text);
        mRequestQueue = Volley.newRequestQueue(this);
        String url ="http://www.baidu.com";
        stringRequest = new StringRequest(Request.Method.GET, url,
                    new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                // Display the first 500 characters of the response string.
                mTextView.setText("Response is: "+ response.substring(0,500));
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                mTextView.setText("That didn‘t work!");
            }
        });
        // Set the tag on the request.
        stringRequest.setTag(TAG);
        // Add the request to the RequestQueue.
        mRequestQueue.add(stringRequest);
    }

    @Override
    protected void onStop() {
        // TODO Auto-generated method stub
        super.onStop();
        if (mRequestQueue != null) {
            mRequestQueue.cancelAll(TAG);
        }
    }
}

最后,一定要AndroidManifest.xml中增加 INTERNET Permission:

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

3. cache–缓存的使用

volley支持cache,下面是一个使用cache的样例:

mTextView = (TextView) findViewById(R.id.text);
Cache cache = new DiskBasedCache(getCacheDir(), 1024 * 1024); // 1MB cap
Network network = new BasicNetwork(new HurlStack());
mRequestQueue = new RequestQueue(cache, network);
mRequestQueue.start();
String url ="http://www.myurl.com";
// Request a string response from the provided URL.
stringRequest = new StringRequest(
   Request.Method.GET,
   url,
   new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
        mTextView.setText("Response is: "+ response.substring(0,500));
            }
        },
    new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
            mTextView.setText("That didn‘t work!");
    }
});
stringRequest.setTag(TAG);
mRequestQueue.add(stringRequest);

4. 使用单例模式应用volley

MySingleton ——单例模式类

import android.content.Context;
import android.graphics.Bitmap;
import android.util.LruCache;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.Volley;

public class MySingleton {
    private static MySingleton mInstance;
    private RequestQueue mRequestQueue;
    private ImageLoader mImageLoader;
    private static Context mCtx;

    private MySingleton(Context context) {
        mCtx = context;
        mRequestQueue = getRequestQueue();
        mImageLoader = new ImageLoader(mRequestQueue,
                new ImageLoader.ImageCache() {
            private final LruCache<String, Bitmap>
                    cache = new LruCache<String, Bitmap>(20);
            @Override
            public Bitmap getBitmap(String url) {
                return cache.get(url);
            }
            @Override
            public void putBitmap(String url, Bitmap bitmap) {
                cache.put(url, bitmap);
            }
        });
    }

    public static synchronized MySingleton getInstance(Context context) {
        if (mInstance == null) {
            mInstance = new MySingleton(context);
        }
        return mInstance;
    }

    public RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {
// getApplicationContext() is key, it keeps you from leaking the
// Activity or BroadcastReceiver if someone passes one in.
            mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
        }
        return mRequestQueue;
    }

    public <T> void addToRequestQueue(Request<T> req) {
        getRequestQueue().add(req);
    }

    public ImageLoader getImageLoader() {
        return mImageLoader;
    }
}

使用样例:

mTextView = (TextView) findViewById(R.id.text);
mRequestQueue = MySingleton.getInstance(this.getApplicationContext()).
                getRequestQueue();
String url ="http://www.baidu.com";
stringRequest = new StringRequest(
    Request.Method.GET,
    url,
    new Response.Listener<String>() {
    @Override
    public void onResponse(String response) {
        mTextView.setText("Response is: "+ response.substring(0,500));
            }
        },
    new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
         mTextView.setText("That didn‘t work!");
    }
});
stringRequest.setTag(TAG);
MySingleton.getInstance(this).addToRequestQueue(stringRequest);

5.ImageRequest + ImageView

ImageRequest 就是Image的请求:

ImageView mImageView;
String url = "http://i.imgur.com/7spzG.png";
mImageView = (ImageView) findViewById(R.id.myImage);
...

// Retrieves an image specified by the URL, displays it in the UI.
ImageRequest request = new ImageRequest(url,
    new Response.Listener<Bitmap>() {
        @Override
        public void onResponse(Bitmap bitmap) {
            mImageView.setImageBitmap(bitmap);
        }
    }, 0, 0, null,
    new Response.ErrorListener() {
        public void onErrorResponse(VolleyError error) {
            mImageView.setImageResource(R.drawable.image_load_error);
        }
    });
// Access the RequestQueue through your singleton class.
MySingleton.getInstance(this).addToRequestQueue(request);

6.ImageLoader + ImageView

ImageLoader mImageLoader;
ImageView mImageView;
// The URL for the image that is being loaded.
private static final String IMAGE_URL =
    "http://developer.android.com/images/training/system-ui.png";
...
mImageView = (ImageView) findViewById(R.id.regularImageView);

// Get the ImageLoader through your singleton class.
mImageLoader = MySingleton.getInstance(this).getImageLoader();
mImageLoader.get(IMAGE_URL, ImageLoader.getImageListener(mImageView,
         R.drawable.def_image, R.drawable.err_image));

7.ImageLoader+NetworkImageView

在ListView中,对于有效的显示多张图片,我们可以采用NetworkImageView 和 ImageLoader来处理。

xml布局文件:

<com.android.volley.toolbox.NetworkImageView
        android:id="@+id/networkImageView"
        android:layout_width="150dp"
        android:layout_height="170dp"
        android:layout_centerHorizontal="true" />

使用样例:

ImageLoader mImageLoader;
NetworkImageView mNetworkImageView;
private static final String IMAGE_URL =
    "http://developer.android.com/images/training/system-ui.png";
...

// Get the NetworkImageView that will display the image.
mNetworkImageView = (NetworkImageView) findViewById(R.id.networkImageView);

// Get the ImageLoader through your singleton class.
mImageLoader = MySingleton.getInstance(this).getImageLoader();

// Set the URL of the image that should be loaded into this view, and
// specify the ImageLoader that will be used to make the request.
mNetworkImageView.setImageUrl(IMAGE_URL, mImageLoader);

8.图片显示的一个综合样例

8.1LruBitmapCache.java

import android.content.Context;
import android.graphics.Bitmap;
import android.support.v4.util.LruCache;
import android.util.DisplayMetrics;
import com.android.volley.toolbox.ImageLoader.ImageCache;

public class LruBitmapCache extends LruCache<String, Bitmap>
        implements ImageCache {

    public LruBitmapCache(int maxSize) {
        super(maxSize);
    }

    public LruBitmapCache(Context ctx) {
        this(getCacheSize(ctx));
    }

    @Override
    protected int sizeOf(String key, Bitmap value) {
        return value.getRowBytes() * value.getHeight();
    }

    @Override
    public Bitmap getBitmap(String url) {
        return get(url);
    }

    @Override
    public void putBitmap(String url, Bitmap bitmap) {
        put(url, bitmap);
    }

    // Returns a cache size equal to approximately three screens worth of images.
    public static int getCacheSize(Context ctx) {
        final DisplayMetrics displayMetrics = ctx.getResources().
                getDisplayMetrics();
        final int screenWidth = displayMetrics.widthPixels;
        final int screenHeight = displayMetrics.heightPixels;
        // 4 bytes per pixel
        final int screenBytes = screenWidth * screenHeight * 4;
        return screenBytes * 3;
    }
}

8.2 activity_main_04.xml

<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=".Lesson01Activity" >

    <TextView
        android:id="@+id/tv01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="ImageView"
        />

    <ImageView
        android:id="@+id/myImage"
        android:layout_below="@id/tv01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/tv02"
        android:layout_below="@id/myImage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="NetworkImageView"
        />

    <com.android.volley.toolbox.NetworkImageView
        android:id="@+id/networkImageView"
        android:layout_below="@id/tv02"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/ic_launcher" />

</RelativeLayout>

8.3 使用样例

public class Lesson04Activity extends Activity {

    public static final String TAG = "Lesson04Activity";
    private static final String IMAGE_URL =     "http://developer.android.com/images/training/system-ui.png";
    private String url = "http://i.imgur.com/7spzG.png";
    private ImageRequest request;
    private RequestQueue mRequestQueue;
    private ImageView myImage;
    private NetworkImageView networkImageView;
    private ImageLoader imageLoader;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_04);
        init();
    }
    private void init() {
        // TODO Auto-generated method stub
        mRequestQueue = MySingleton.getInstance(this.getApplicationContext()).
                getRequestQueue();
        networkImageView = (NetworkImageView) findViewById(R.id.networkImageView);
    networkImageView.setImageResource(R.drawable.ic_launcher);
        //imageLoader = MySingleton.getInstance(this).getImageLoader();
        imageLoader = new ImageLoader(mRequestQueue, new LruBitmapCache(
                LruBitmapCache.getCacheSize(this)));
        //imageLoader.get(url, ImageLoader.getImageListener(networkImageView,
        //         R.drawable.ic_launcher, R.drawable.ic_launcher));
        //networkImageView.setImageUrl(IMAGE_URL, imageLoader);
        //networkImageView.setImageUrl(url, imageLoader);

        myImage = (ImageView) findViewById(R.id.myImage);
        myImage.setImageResource(R.drawable.ic_launcher);
        request = new ImageRequest(url,
                new Response.Listener<Bitmap>() {
                    @Override
                    public void onResponse(Bitmap bitmap) {
                        // TODO Auto-generated method stub
                        myImage.setImageBitmap(bitmap);
                    }
                }, 0, 0, null,
                new Response.ErrorListener() {

                    @Override
                    public void onErrorResponse(VolleyError arg0) {
                        // TODO Auto-generated method stub
                        myImage.setImageResource(R.drawable.ic_launcher);
                    }
                });
        request.setTag(TAG);
    MySingleton.getInstance(this).addToRequestQueue(request);
    }

    @Override
    protected void onStop() {
        // TODO Auto-generated method stub
        super.onStop();
        if (mRequestQueue != null) {
            mRequestQueue.cancelAll(TAG);
        }
    }
}

9.JSON requests

Volley provides the following classes for JSON requests:

JsonArrayRequest—A request for retrieving a JSONArray response body at a given URL.

JsonObjectRequest—A request for retrieving a JSONObject response body at a given URL, allowing for an optional JSONObject to be passed in as part of the request body.

Both classes are based on the common base class JsonRequest.

使用样例:

mTextView = (TextView) findViewById(R.id.text);
mRequestQueue = Volley.newRequestQueue(this);
//String url = "http://my-json-feed";
String url = "http://api.androidhive.info/volley/person_object.json";
JsonObjectRequest jsObjRequest = new JsonObjectRequest(
Request.Method.GET,
url,
null,
new Response.Listener<JSONObject>() {
    @Override
    public void onResponse(JSONObject response) {
    // TODO Auto-generated method stub
    mTextView.setText("Response: " + response.toString());
    }
},
new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError response) {
    // TODO Auto-generated method stub
    mTextView.setText("Response: " + response.toString());
    }
});
MySingleton.getInstance(this).addToRequestQueue(jsObjRequest);

.10 自定义Response

For cases where you do need to implement a custom request, this is all you need to do:

1.Extend the Request class, where represents the type of parsed response the request expects. So if your parsed response is a string, for example, create your custom request by extending Request. See the Volley toolbox classes StringRequest and ImageRequest for examples of extending Request.

2.Implement the abstract methods parseNetworkResponse() and deliverResponse(), described in more detail below.

一个样例:

public class GsonRequest<T> extends Request<T> {
    private final Gson gson = new Gson();
    private final Class<T> clazz;
    private final Map<String, String> headers;
    private final Listener<T> listener;

    /**
     * Make a GET request and return a parsed object from JSON.
     *
     * @param url URL of the request to make
     * @param clazz Relevant class object, for Gson‘s reflection
     * @param headers Map of request headers
     */
    public GsonRequest(String url, Class<T> clazz, Map<String, String> headers,
            Listener<T> listener, ErrorListener errorListener) {
        super(Method.GET, url, errorListener);
        this.clazz = clazz;
        this.headers = headers;
        this.listener = listener;
    }

    @Override
    public Map<String, String> getHeaders() throws AuthFailureError {
        return headers != null ? headers : super.getHeaders();
    }

    @Override
    protected void deliverResponse(T response) {
        listener.onResponse(response);
    }

    @Override
    protected Response<T> parseNetworkResponse(NetworkResponse response) {
        try {
            String json = new String(
                    response.data,
                    HttpHeaderParser.parseCharset(response.headers));
            return Response.success(
                    gson.fromJson(json, clazz),
                    HttpHeaderParser.parseCacheHeaders(response));
        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        } catch (JsonSyntaxException e) {
            return Response.error(new ParseError(e));
        }
    }
}

源码下载地址

参考资料

  1. https://developer.android.com/intl/zh-cn/training/volley/index.html

    Transmitting Network Data Using Volley

    2.http://www.androidhive.info/2014/05/android-working-with-volley-library-1/

    Android working with Volley Library

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-08 06:35:09

Android Volley (1)的相关文章

Android Volley 之自定义Request

可以在Ext.QuickTips.init();后加入如下代码: Ext.MessageBox.buttonText = { ok : "确定", cancel : "取消", yes : "是", no : "否" }; Android Volley 之自定义Request,码迷,mamicode.com

Android Volley入门到精通:定制自己的Request

经过前面两篇文章的学习,我们已经掌握了Volley各种Request的使用方法,包括StringRequest.JsonRequest.ImageRequest等.其中StringRequest用于请求一条普通的文本数据,JsonRequest(JsonObjectRequest.JsonArrayRequest)用于请求一条JSON格式的数据,ImageRequest则是用于请求网络上的一张图片. 可是Volley提供给我们的Request类型就只有这么多,而我们都知道,在网络上传输的数据通常

Android Volley网络通讯框架(Google)

Volley主页 https://android.googlesource.com/platform/frameworks/volley http://www.youtube.com/watch?v=yhv8l9F44qo&feature=player_embedded 1. 什么是Volley 在这之前,我们在程序中需要和网络通信的时候,大体使用的东西莫过于AsyncTaskLoader,HttpURLConnection,AsyncTask,HTTPClient(Apache)等,今年的Go

Android Volley分析(二)——实现

在Android Volley分析(一)--结构中主要分析了Volley的基本组件和框架结构,组件主要是定义的接口,也就是说我们可以实现这些接口来定制自己的Volley版本,比如NetWork.Cache.Request等等.Android Volley在com.android.volley.toolbox下已经做了这些工作,下面就看看这些具体的实现内容 先看一个Volley使用的例子 final TextView mTextView = (TextView) findViewById(R.id

很急!!! java.lang.NoClassDefFoundError: com.android.volley.toolbox.Volley

============问题描述============ 日志文件如下,不知道是什么原因报如下错误 08-01 16:33:35.001: E/AndroidRuntime(31240): FATAL EXCEPTION: main 08-01 16:33:35.001: E/AndroidRuntime(31240): Process: cn.phonecms.main, PID: 31240 08-01 16:33:35.001: E/AndroidRuntime(31240): java.

[Android]Volley源码分析(四)

上篇中有提到NetworkDispatcher是通过mNetwork(Network类型)来进行网络访问的,现在来看一下关于Network是如何进行网络访问的. Network部分的类图: Network有一个实现类BasicNetwork,它有一个mHttpStack的属性,实际的网络请求是由这个mHttpStack来进行的,看BasicNetwork的performRequest()方法, 1 @Override 2 public NetworkResponse performRequest

Android Volley入门到精通:使用Volley加载网络图片

在上一篇文章中,我们了解了Volley到底是什么,以及它的基本用法.本篇文章中我们即将学习关于Volley更加高级的用法,如何你还没有看过我的上一篇文章的话,建议先去阅读Android Volley完全解析(一),初识Volley的基本用法. 在上篇文章中有提到过,Volley是将AsyncHttpClient和Universal-Image-Loader的优点集成于一身的一个框架.我们都知道,Universal-Image-Loader具备非常强大的加载网络图片的功能,而使用Volley,我们

[Android]Volley源码分析(二)Cache

Cache作为Volley最为核心的一部分,Volley花了重彩来实现它.本章我们顺着Volley的源码思路往下,来看下Volley对Cache的处理逻辑. 我们回想一下昨天的简单代码,我们的入口是从构造一个Request队列开始的,而我们并不直接调用new来构造,而是将控制权反转给Volley这个静态工厂来构造. com.android.volley.toolbox.Volley: public static RequestQueue newRequestQueue(Context conte

[Android]Volley源码分析(叁)Network

如果各位看官仔细看过我之前的文章,实际上Network这块的只是点小功能的补充.我们来看下NetworkDispatcher的核心处理逻辑: <span style="font-size:18px;">while (true) { try { // Take a request from the queue. request = mQueue.take(); } catch (InterruptedException e) { // We may have been int

[Android]Volley源码分析(肆)应用

通过前面的讲述,相信你已经对Volley的原理有了一定了解.本章将举一些我们能在应用中直接用到的例子,第一个例子是 NetworkImageView类,其实NetworkImageView顾名思义就是将异步的操作封装在了控件本身,这种设计可以充分保留控件的移植性和维护性.NetworkImageView通过调用setImageUrl来指定具体的url: public void setImageUrl(String url, ImageLoader imageLoader) { mUrl = ur