Volley
除了简单易用之外,Volley在性能方面也进行了大幅度的调整,它的设计目标就是非常适合去进行数据量不大,但通信频繁的网络操作,而对于大数据量的网络操作,比如说下载文件等,Volley的表现就会非常糟糕。
Volley提供的功能:
- JSON,图像等的异步下载;
- 网络请求的排序(scheduling)
- 网络请求的优先级处理
- 缓存
- 多级别取消请求
- 和Activity和生命周期的联动
安装volley
添加权限(以下所有的例子都需要此权限)
<uses-permission android:name="android.permission.INTERNET" />
<!--在安卓9.0版本后,要在< application>中添加android:networkSecurityConfig属性
如果闪退可以添加<uses-library android:name="org.apache.http.legacy" android:required="false"/>-->
<application android:networkSecurityConfig="@xml/security_config">
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
</application>
<!--xml/security_config。xml-->
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true"/>
</network-security-config>
StringRequest
RequestQueue是一个请求队列 对象,它可以缓存所有的HTTP请求,然后按照一定的算法并发地发出这些请求。RequestQueue内部的设计就是非常合适高并发的,因此我们不必为 每一次HTTP请求都创建一个RequestQueue对象,这是非常浪费资源的。基本在每一个需要和网络交互的Activity中创建一个RequestQueue对象就足够了。
创建队列
RequestQueue queue = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//创建请求队列
queue = Volley.newRequestQueue(this);
}
单击按钮事件
不带参数的字符串请求:
//发送一个字符串的请求
public void sendStringRequestClick(View view){
String url = "https://www.baidu.com";
//参数(目标服务器的URL地址,服务器响应成功的回调,服务器响应失败的回调)
StringRequest request = new StringRequest(Request.Method.GET,
url, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
System.out.println(response);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
System.out.println(error);
}
});
queue.add(request);
}
发送一个带参数的POST字符串请求:
//发送一个带参数的POST请求
public void sendParamsPostStringRequestClick(View view){
String url="http://10.0.2.2:8080/HttpURL/XMLServlet";
StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
System.out.println(response);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
System.out.println(error);
}
}){
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> params = new HashMap<>();
params.put("name","vince");
return params;
}
};
queue.add(request);
}
JsonRequest
public void sendJsonRequestClick(View v){
String url = "http://weather.123.duba.net/static/weather_info/101010100.html";
//请求参数封装为JSONObject
// JSONObject jsonObject = new JSONObject();
// try {
// jsonObject.put("name","value");
// } catch (JSONException e) {
// e.printStackTrace();
// }
//参数(请求方式,URL,请求参数,响应的回调接口,错误的回调接口)
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
System.out.println(response);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
System.out.println(error);
}
});
queue.add(request);
}
ImageRequest
//发送一个ImageRequest
public void sendImageRequestClick(View view){
//网上找的地址
String url = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1555503622777&di=3f21b66d5df95e13ccfcdc8b1403afbc&imgtype=0&src=http%3A%2F%2Fimg8.zol.com.cn%2Fbbs%2Fupload%2F21166%2F21165821.JPG";
//参数(URL,图片请求成功的回调,允许图片最大的宽和高,指定图片的颜色,图片请求失败的回调)
ImageRequest request = new ImageRequest(url, new Response.Listener<Bitmap>() {
@Override
public void onResponse(Bitmap response) {
imageView.setImageBitmap(response);
}
}, 0, 0, Bitmap.Config.RGB_565, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
System.out.println(error);
}
});
queue.add(request);
}
ImageLoader
ImageLoader也可以用于加载网络图片,内部也是使用ImageRequest来实现的,不过ImageLoader明显比ImageRequest更加高效,因为不仅仅可以对图片进行缓存,还可以过滤掉重复的链接,避免重复发送请求。
基础实现
//使用ImageLoader加载图片
public void imageLoaderClick(View view){
String url = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1555503622777&di=3f21b66d5df95e13ccfcdc8b1403afbc&imgtype=0&src=http%3A%2F%2Fimg8.zol.com.cn%2Fbbs%2Fupload%2F21166%2F21165821.JPG";
ImageLoader imageLoader = new ImageLoader(queue, new ImageLoader.ImageCache() {
@Override
public Bitmap getBitmap(String url) {
return null;
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
}
});
//获取图片监听器(参数:imageView,获取之前显示的图片,获取失败显示的图片)
ImageLoader.ImageListener imageListener = ImageLoader.getImageListener(imageView,R.mipmap.ic_launcher,R.mipmap.ic_launcher);
imageLoader.get(url,imageListener);
}
带缓存的ImageCache
//使用ImageLoader加载图片
public void imageLoaderClick(View view){
String url = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1555503622777&di=3f21b66d5df95e13ccfcdc8b1403afbc&imgtype=0&src=http%3A%2F%2Fimg8.zol.com.cn%2Fbbs%2Fupload%2F21166%2F21165821.JPG";
ImageLoader imageLoader = new ImageLoader(queue, new BitmapCache());
//获取图片监听器(参数:imageView,获取之前显示的图片,获取失败显示的图片)
ImageLoader.ImageListener imageListener = ImageLoader.getImageListener(imageView,R.mipmap.ic_launcher,R.mipmap.ic_launcher);
imageLoader.get(url,imageListener);
}
//用于图片缓存
private class BitmapCache implements ImageLoader.ImageCache{
private LruCache<String, Bitmap> cache;
private int maxSize = 10*1024;
public BitmapCache(){
cache = new LruCache<String, Bitmap>(maxSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
return bitmap.getRowBytes() * bitmap.getHeight();
}
};
}
@Override
public Bitmap getBitmap(String url) {
return cache.get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
cache.put(url,bitmap);
}
}
NetworkImageView
private NetworkImageView networkImageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//创建请求队列
queue = Volley.newRequestQueue(this);
networkImageView = (NetworkImageView)findViewById(R.id.network_image);
networkImageView();
}
public void networkImageView(){
networkImageView.setDefaultImageResId(R.mipmap.ic_launcher);
networkImageView.setErrorImageResId(R.mipmap.ic_launcher);
String url = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1555503622777&di=3f21b66d5df95e13ccfcdc8b1403afbc&imgtype=0&src=http%3A%2F%2Fimg8.zol.com.cn%2Fbbs%2Fupload%2F21166%2F21165821.JPG";
networkImageView.setImageUrl(url,new ImageLoader(queue,new BitmapCache()));
}
自定义Request
import android.util.Xml;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.toolbox.HttpHeaderParser;
import com.android.volley.toolbox.StringRequest;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
public class XMLRequest extends Request<XmlPullParser> {
private final Response.Listener<XmlPullParser> mListener;
public XMLRequest(int method, String url, Response.Listener<XmlPullParser> listener, Response.ErrorListener elistener) {
super(method, url,elistener);
this.mListener = listener;
}
@Override
protected Response<XmlPullParser> parseNetworkResponse(NetworkResponse response) {
String xmlString = null;
try {
xmlString = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
XmlPullParser pull = Xml.newPullParser();
pull.setInput(new StringReader(xmlString));
return Response.success(pull,HttpHeaderParser.parseCacheHeaders(response));
} 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 response) {
mListener.onResponse(response);
}
}
自定义GsonRequest
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.toolbox.HttpHeaderParser;
import com.google.gson.Gson;
import java.io.UnsupportedEncodingException;
public class GsonRequest<T> extends Request<T> {
private final Response.Listener<T> mListener;
private Gson gson;
private Class<T> mClass;
public GsonRequest(int method, String url,Class<T> mClass, Response.Listener<T> mListener, Response.ErrorListener listener) {
super(method, url, listener);
this.mListener = mListener;
this.mClass = mClass;
}
@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString = jsonString = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
return Response.success(gson.fromJson(jsonString,mClass),
HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return Response.error(new ParseError(e));
}
}
@Override
protected void deliverResponse(T response) {
mListener.onResponse(response);
}
}