volley也是一款与okhttp类似的网络通信框架,但是也是有区别的,volley适用于频繁多次的网络请求,而且自带图片缓存和异步请求,除此之外,volley的请求非常简单,但是性能不如okhttp,如一些大文件的处理,还有一点说volley不支持HTTPS请求,但是我试了一下也是有数据返回的,所以本人有点疑惑,或者有哪位大神指点一下迷津。下面开始:
首先导入包,自行下载并且导入到项目中下载链接
下面是代码:
1、字符串类型请求
//首先实例化一个请求队列,一般用一个足够了
RequestQueue requestQueue = Volley.newRequestQueue(VolleyTestActivity.this);
//实例化请求类型(有多种),并传入相应参数,
StringRequest stringRequest = new StringRequest(Request.Method.GET,
"http://www.cnblogs.com/rocomp/p/5504475.html",
new Response.Listener<String>() {
@Override
public void onResponse(String s) {
Toast.makeText(VolleyTestActivity.this, s, Toast.LENGTH_LONG).show();
Log.i(TAG, "String_Request: \n{" + s + "\n}");
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
Log.e(TAG, "String_Request: " + volleyError.getMessage(), volleyError);
Toast.makeText(VolleyTestActivity.this, "出错了", Toast.LENGTH_SHORT).show();
}
}) {
@Override
protected Map<String, String> getParams() throws AuthFailureError {
return super.getParams();
}
};
//最重要的一步别忘了,否则没有效果,将请求添加到请求队列中
requestQueue.add(stringRequest);
2、JsonObject类型请求(与上面基本没区别,JsonArray同理)
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET,
"http://baike.baidu.com/api/openapi/BaikeLemmaCardApi?scope=103&format=json&appid=379020&bk_key=Android&bk_length=600", null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject jsonObject) {
Toast.makeText(VolleyTestActivity.this, jsonObject.toString(), Toast.LENGTH_LONG).show();
Log.i(TAG, "JsonObject_Request: \n" + jsonObject.toString() + "\n");
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
Log.e(TAG, "JsonObject_Request: " + volleyError.getMessage(), volleyError);
Toast.makeText(VolleyTestActivity.this, "出错了", Toast.LENGTH_SHORT).show();
}
}) {
@Override
protected Map<String, String> getParams() throws AuthFailureError {
return super.getParams();
}
};
requestQueue.add(jsonObjectRequest);
3、Image类型请求
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
ImageRequest imageRequest = new ImageRequest("http://richd.com/pictures/richd-android1920.jpg",
new Response.Listener<Bitmap>() {
@Override
public void onResponse(Bitmap bitmap) {
iv.setImageBitmap(bitmap);
}
}, 0, 0, Bitmap.Config.RGB_565, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
//Drawable着色
Drawable originadrawable = ContextCompat.getDrawable(getApplicationContext(), R.drawable.close);
Drawable tintdrawable = DrawableCompat.wrap(originadrawable).mutate();
DrawableCompat.setTint(tintdrawable, Color.parseColor("#FFFF2200"));
iv.setImageDrawable(tintdrawable);
Log.e(TAG, "JsonObject_Request: " + volleyError.getMessage(), volleyError);
Toast.makeText(VolleyTestActivity.this, "加载图片出错了", Toast.LENGTH_SHORT).show();
}
});
requestQueue.add(imageRequest);
图片着色
这里用到了图片着色,在实际开发中这是非常有用的,可以节省资源和内存,仅仅对已有图片改变颜色就可以用在其他地方,如下是代码动态着色
Drawable originadrawable = ContextCompat.getDrawable(getApplicationContext(), R.drawable.close);
//这里的mutate方法作用是复制一份原有图像出来着色,否则将对原图颜色改变,因为Android系统内部资源id最终指向的是同一个
//资源,如果不加此方法,就等于将原来图片着色了,其他地方调用的也是这个资源ID
Drawable tintdrawable = DrawableCompat.wrap(originadrawable).mutate();
DrawableCompat.setTint(tintdrawable, Color.parseColor("#FFFF2200"));
//这里的ImageView或者控件必须再次设置否则效果不会改变。
iv.setImageDrawable(tintdrawable);
当然也可用XML文件着色,通过tint属性,这样更方便、简介,只是不能动态改变
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/image2"
android:src="@mipmap/icon"
android:tint="#FFCDD2"
/>
还有背景着色,用android:backgroundTint属性即可改变,前提是设置了background。
4、ImageLoader类型请求
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
ImageLoader.ImageListener imageListener = ImageLoader.getImageListener(iv, R.drawable.default_icon,
R.drawable.error_icon);
// ImageLoader imageLoader = new ImageLoader(requestQueue, new BitmapCache());//使用图片缓存策略
ImageLoader imageLoader = new ImageLoader(requestQueue, new ImageLoader.ImageCache() {//未使用缓存
@Override
public Bitmap getBitmap(String s) {
return null;
}
@Override
public void putBitmap(String s, Bitmap bitmap) {
}
});
imageLoader.get("http://image.dhgate.com/albu_212507313_00/1.0x0.jpg", imageListener, 0, 0);
这里用到图片缓存的类BitmapCache
public class BitmapCache implements ImageLoader.ImageCache {
private LruCache<String, Bitmap> mMemory;
public BitmapCache() {
//获取程序分配的最大内存值,若超出则出现OOM
int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
//设置图片缓存大小为总内存的1/8
int cachSize = maxMemory / 8;
mMemory = new LruCache<String, Bitmap>(cachSize) {
@Override
protected int sizeOf(String key, Bitmap value) {
// 重写此方法来衡量每张图片的大小,默认返回图片数量
return value.getByteCount() / 1024;
}
};
}
@Override
public Bitmap getBitmap(String s) {
return mMemory.get(s);
}
@Override
public void putBitmap(String s, Bitmap bitmap) {
if (getBitmap(s) == null) {
mMemory.put(s, bitmap);
}
}
}
5、NetWorkImageView(一个控件,可在XML中实现的,个人认为也是最简单和最好用的针对缓存图片)
XML
<com.android.volley.toolbox.NetworkImageView
android:id="@+id/network_image_view"
android:layout_width="180dp"
android:layout_height="180dp"
android:scaleType="centerCrop" />
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
ImageLoader imageLoader = new ImageLoader(requestQueue, new BitmapCache());//使用图片缓存策略
networkImageView.setErrorImageResId(R.drawable.error_icon);
networkImageView.setDefaultImageResId(R.drawable.default_icon);
networkImageView.setImageUrl("http://pic.baike.soso.com/p/20131202/20131202103359-1685722094.jpg", imageLoader);
6、自定义请求类型
public class CustomXMLRequest extends Request<XmlPullParser> {
private final Response.Listener<XmlPullParser> mListener;
public CustomXMLRequest(String url, Response.ErrorListener listener, Response.Listener<XmlPullParser> mListener) {
this(Method.GET, url, listener, mListener);
}
public CustomXMLRequest(int method, String url, Response.ErrorListener listener, Response.Listener<XmlPullParser> mListener) {
super(method, url, listener);
this.mListener = mListener;
}
@Override
protected Response<XmlPullParser> parseNetworkResponse(NetworkResponse networkResponse) {
try {
String xmlString = new String(networkResponse.data, HttpHeaderParser.parseCharset(networkResponse.headers));
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser pullParser = factory.newPullParser();
pullParser.setInput(new StringReader(xmlString));
return Response.success(pullParser, HttpHeaderParser.parseCacheHeaders(networkResponse));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return Response.error(new ParseError(e));
} catch (XmlPullParserException e) {
e.printStackTrace();
return Response.error(new ParseError(e));
}
}
@Override
protected void deliverResponse(XmlPullParser xmlPullParser) {
this.mListener.onResponse(xmlPullParser);
}
}
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
CustomXMLRequest xmlRequest = new CustomXMLRequest(0, "http://flash.weather.com.cn/wmaps/xml/china.xml",
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
Log.i(TAG, "onErrorResponse: " + volleyError.getMessage());
}
}, new Response.Listener<XmlPullParser>() {
@Override
public void onResponse(XmlPullParser xmlPullParser) {
try {
Toast.makeText(VolleyTestActivity.this, xmlPullParser.toString(), Toast.LENGTH_LONG).show();
int eventType = xmlPullParser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_TAG:
String name = xmlPullParser.getName();
if (name.equals("city")) {
String pName = xmlPullParser.getAttributeValue(0);
Log.i(TAG, "onResponse: " + pName);
}
break;
}
eventType = xmlPullParser.next();
}
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
requestQueue.add(xmlRequest);
总的来说,几种请求类型都是异曲同工的,只是小改动而已。