Android Volley网络框架使用笔记

Volley简介及现状

  • Volley是谷歌2013年在I/O大会期间推出的网络库。开发Volley是因为在Android SDK中缺乏一个用户体验良好的网络加载类。
  • Volley自身的特点在于:适合去进行数据量不大,但通信频繁的网络操作;而对于大数据量的网络操作,例如上传/下载文件,其表现就不怎么给力了。

由于OkHttp的优异的表现和性能,Volley使用量逐渐减少,更不要说OkHttp的升级版Retrofit的异军突起。
但是作为一款优秀的网络框架,我们还是要简单了解一下其使用的。
本文就结合demo简单介绍一下如何Volley使用。

添加依赖

有趣的一点是,与其它很多常见的开源库的导入不同,Volley自身是没有提供官方的Maven或者说Jcenter Repository的。

Android Studio可以直接工程或者项目的build.gradle下添加依赖即可:

dependencies {
    ...
    compile 'com.mcxiaoke.volley:library:1.0.19'
    ...
}

使用介绍

  • 常见的request请求类型有三种:StringRequest、ImageRequest、JsonRequest
  • 常见的请求方式有:默认是0,即get请求
    /**
     * 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;
    }
  • RequestQueue会将多个HTTP请求缓存进队列,然后按照一定的算法分别去执行这些请求。
    所以,通常我们很显然没有必要将这个东西在每次需要发起请求时都去new一次,可以将RequestQueue设计为单例来节约资源。
  • 为request请求对象,设置一些必要的策略,如重试策略等。
  • 将得到RequestQueue与Request对象,然后将request添加到请求队列中就可以了。

StringRequest请求类型

1.GET
    public static void get(Context context, String url) {
  RequestQueue requestQueue = Volley.newRequestQueue(this);
      //因为默认请求方式为get,StringRequest()方法的第一个参数无需设置
        StringRequest request = new StringRequest(url, new Response.Listener() {
            @Override
            public void onResponse(String response) {
                Log.d(TAG, response);
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.d(TAG, error.toString());
            }
        });
        requestQueue.add(request);
    }
2.POST
 public static void post(Context context, String url, final Map map) {
        RequestQueue requestQueue = Volley.newRequestQueue(this);
        //StringRequest()方法的第一个参数设置为Request.Method.POST,即post请求
        StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener() {
            @Override
            public void onResponse(String response) {
                Log.d(TAG, response);
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.d(TAG, error.toString());
            }
        }) {
            @Override
            protected Map getParams() throws AuthFailureError {
                return map;//请求参数Map类型
            }
        };
        //对Request设置重试策略时,更改默认超时时间为5000
        //由于重试策略,如果默认超时时间过短,请求参数过大,会出现请求参数重复上传的现象
        request.setRetryPolicy(new DefaultRetryPolicy(5000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        requestQueue.add(request);
    }

JsonRequest

JsonRequest顾名思义,就是说服务器响应的数据类型是JSON格式的,而对于其使用,与StringRequest是很相似的。
由于String与Json的转换时很简单的,所以两种方式任选其一即可。

 JsonObjectRequest request = new JsonObjectRequest(url, new Response.Listener() {
            @Override
            public void onResponse(JSONObject response) {

            }
        },null);

ImageRequest

从名字我们可以看到这个类显然就是为了图片专门封装的,相比StringRequest和JsonRequest稍有不同了。(JSON就只是指定了格式的文字而已)
但也是由于Volley本身封装的比较好,所以虽然不再是响应文字而是响应图片,但使用起来也很简单。

 ImageRequest request = new ImageRequest(url, new Response.Listener() {
            @Override
            public void onResponse(Bitmap response) {
                //imageView.setImageBitmap(response);
            }
        },maxWidth,maxHeight,scaleType,decodeConfig,errListener);

maxWidth //图片最大宽度
maxHeight//图片最大高度
scaleType //指定图片缩放类型

ImageLoader

对于图片的下载显示,Volley还提供了一个相较ImageRequest更加强力一点的东东ImageLoader,关于其使用其实也不复杂。

    /**
     * 缓存策略根据url处理图片
     * 将图片直接显示在ImageView上
     * 比ImageRequest效率高
     *
     * @param context
     * @param url
     * @param view
     */
    public static void ImageLoader(Context context, String url, ImageView view) {
        if (requestQueue == null) {
            requestQueue = getQueue(context.getApplicationContext());
        }
        final LruCache mImageCache = new LruCache(20);
        ImageLoader.ImageCache imageCache = new ImageLoader.ImageCache() {
            @Override
            public Bitmap getBitmap(String s) {
                return mImageCache.get(s);
            }

            @Override
            public void putBitmap(String s, Bitmap bitmap) {
                mImageCache.put(s, bitmap);
            }
        };
        ImageLoader imageLoader = new ImageLoader(requestQueue, imageCache);
        ImageLoader.ImageListener listener = ImageLoader.getImageListener(view, R.mipmap.ic_launcher, R.mipmap
                .ic_launcher);
        imageLoader.get(url, listener);
    }

Demo

1.VolleyModel

  1. 使用单例模式获取RequestQueue对象
  2. 为了将获取的结果传递到View,使用接口传递
  3. 对于需要上传请求参数的post,必要时需要设置策略时间。
public class VolleyModel {
    private static final String TAG = "VolleyModel";
    private volatile static RequestQueue requestQueue;

    /**
     * 单例模式,双重校验锁
     *
     * @param context
     * @return
     */
    public static RequestQueue getQueue(Context context) {
        if (requestQueue == null) {
            synchronized (VolleyModel.class) {
                if (requestQueue == null) {
                    requestQueue = Volley.newRequestQueue(context.getApplicationContext());
                }
            }
        }
        return requestQueue;
    }

    /**
     * get请求
     *
     * @param context
     * @param url      接口地址
     * @param callBack 回调函数
     */
    public static void get(Context context, String url, final ICallBack callBack) {
        if (requestQueue == null) {
            requestQueue = getQueue(context);
        }
        StringRequest request = new StringRequest(url, new Response.Listener() {
            @Override
            public void onResponse(String response) {
                Log.d(TAG, response);
                callBack.result(response);
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.d(TAG, error.toString());
            }
        });
        requestQueue.add(request);
    }

    /**
     * post请求
     *
     * @param context
     * @param url      接口地址
     * @param map      请求参数
     * @param callBack
     */
    public static void post(Context context, String url, final Map map, final ICallBack callBack) {
        if (requestQueue == null) {
            requestQueue = getQueue(context);
        }
        StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener() {
            @Override
            public void onResponse(String response) {
                Log.d(TAG, response);
                callBack.result(response);
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.d(TAG, error.toString());
            }
        }) {
            @Override
            protected Map getParams() throws AuthFailureError {
                return map;
            }
        };
        //对Request设置重试策略时,更改默认超时时间为5000
        //由于重试策略,如果默认超时时间过短,请求参数过大,会出现请求参数重复上传的现象
        request.setRetryPolicy(new DefaultRetryPolicy(5000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        requestQueue.add(request);
    }

    /**
     * image图片相关请求
     *
     * @param context
     * @param url      图片地址
     * @param callBack 接口回调
     */
    public static void image(Context context, String url, final ICallBack callBack) {
        if (requestQueue == null) {
            requestQueue = getQueue(context);
        }
        ImageRequest request = new ImageRequest(url, new Response.Listener() {
            @Override
            public void onResponse(Bitmap response) {
                callBack.result(response);
            }
        }, 480, 600, ImageView.ScaleType.FIT_XY, Bitmap.Config.RGB_565, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.d(TAG, error.toString());
            }
        });
        requestQueue.add(request);
    }

    /**
     * 缓存策略根据url处理图片
     * 将图片直接显示在ImageView上
     * 比ImageRequest效率高
     *
     * @param context
     * @param url
     * @param view
     */
    public static void ImageLoader(Context context, String url, ImageView view) {
        if (requestQueue == null) {
            requestQueue = getQueue(context.getApplicationContext());
        }
        final LruCache mImageCache = new LruCache(20);
        ImageLoader.ImageCache imageCache = new ImageLoader.ImageCache() {
            @Override
            public Bitmap getBitmap(String s) {
                return mImageCache.get(s);
            }

            @Override
            public void putBitmap(String s, Bitmap bitmap) {
                mImageCache.put(s, bitmap);
            }
        };
        ImageLoader imageLoader = new ImageLoader(requestQueue, imageCache);
        ImageLoader.ImageListener listener = ImageLoader.getImageListener(view, R.mipmap.ic_launcher, R.mipmap
                .ic_launcher);
        imageLoader.get(url, listener);
    }


}

2.ICallBack

接口回调,在Model与View中传递结果。

public interface ICallBack {
    void result(Object object);
}

3.xml布局


<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="demon.volly.MainActivity">

    <TextView
        android:id="@+id/text1"
        android:layout_width="match_parent"
        android:layout_height="100dp"/>

    <TextView
        android:id="@+id/text2"
        android:layout_width="match_parent"
        android:layout_height="100dp"/>

    <ImageView
        android:id="@+id/image1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <ImageView
        android:id="@+id/image2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

LinearLayout>

4.MainActivity

API免费测试接口:http://www.bejson.com/knownjson/webInterface/

public class MainActivity extends AppCompatActivity {
    //京东获取单个商品价格接口:
    String geturl = "http://p.3.cn/prices/mgets?skuIds=J_954086&type=1";
    //阿里云根据地区名获取经纬度接口
    String posturl = "http://gc.ditu.aliyun.com/geocoding";
    //图片链接
    String imageurl = "http://images.csdn.net/20150817/1.jpg";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final ImageView image1 = (ImageView) findViewById(R.id.image1);
        final ImageView image2 = (ImageView) findViewById(R.id.image2);
        final TextView text1 = (TextView) findViewById(R.id.text1);
        final TextView text2 = (TextView) findViewById(R.id.text2);

        VolleyModel.get(this, geturl, new ICallBack() {
            @Override
            public void result(Object object) {
                String s = (String) object;
                text1.setText(s);
            }
        });

        Map map = new HashMap<>();
        map.put("a", "苏州市");
        VolleyModel.post(this, posturl, map, new ICallBack() {
            @Override
            public void result(Object object) {
                String s = (String) object;
                text2.setText(s);
            }
        });

        VolleyModel.image(this, imageurl, new ICallBack() {
            @Override
            public void result(Object object) {
                Bitmap bitmap = (Bitmap) object;
                image1.setImageBitmap(bitmap);
            }
        });

        VolleyModel.ImageLoader(this, imageurl, image2);
    }
}

5.效果图

Android Volley网络框架使用笔记_第1张图片

Module代码下载

代码下载CSDN:http://download.csdn.net/download/demonliuhui/9953753

参考

http://blog.csdn.net/ghost_programmer/article/details/52333877

你可能感兴趣的:(Android框架/机制)