Volley作为谷歌推出的一个网络库,用于解决复杂网络环境下网络请求问题,网络连接会新起一个线程,Volley有个缓存机制,得到URL去缓存区查找,如果访问过直接用返回值连接网络,如果没有访问过则进入线程池,线程池的线程有上限,到达上限后就会使用队列机制排队,由于是写好的框架,所以使用起来比URLConnection要简单,需要掌握单例、doGet、doPost方法。Volley的机制官方示意图:
用法:
- 网络连接权限
- 下载jar包,在studio中直接搜索volley,选择最新的一个jar包即可,在eclipse中需要下载jar包手动导入lib文件下
- 按照API步骤使用Volley,(点击事件中)RequestQueue(请求队列)、StringRequest(请求) 、queue.add()
【StringRequest有四个参数,method、url、两个监听(返回和返回出错)】
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.button_volleyconnect:
RequestQueue queue= Volley.newRequestQueue(getApplication());
StringRequest request=new StringRequest(Request.Method.GET, "http://www.360.com", new Response.Listener<String>() {
@Override
public void onResponse(String response) {
mTextview_show.setText(response);//连接URL
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
mTextview_show.setText("无网络连接");//error
}
});
queue.add(request);//添加之后新建一个线程
break;
}
但是这样写是有缺陷的,每次点击button都会新建一个请求队列消耗内存而一个app只有24M内存,所以把初始化请求队列单例出来,然后再添加一个NetworkImageView,这个控件是在Volley中的,现在主流加载网络图片是imageloader框架(应用只有一句代码),现在只是试用一下
单例(API上有):
public class MySingleton {
private static MySingleton mInstance;
private RequestQueue mRequestQueue;
private ImageLoader mImageLoader;
private static Context mCtx;
private MySingleton(Context context) {//私有化构造器(get请求队列必须有个context,那就传过来)
mCtx = context;
mRequestQueue = getRequestQueue();
//imageloader的单例(这是个搭头儿~)
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) {//synchronized(这是在多线程里)
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) {//在这个方法写的add,使用add就调这个方法
getRequestQueue().add(req);
}
public ImageLoader getImageLoader() {
return mImageLoader;
}
}
doGet方法的用法(单例就是省略了注释掉的这两行代码,但是节省内存):
case R.id.button_volleyconnect:
// RequestQueue queue= Volley.newRequestQueue(getApplication());
StringRequest request=new StringRequest(Request.Method.GET, "http://www.360.com", new Response.Listener<String>() {
@Override
public void onResponse(String response) {
mTextview_show.setText(response);//连接URL
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
mTextview_show.setText("无网络连接");//error
}
});
MySingleton.getInstance(getApplicationContext()).addToRequestQueue(request);
//queue.add(request);添加之后新建一个线程
break;
doPost方法的用法(和doGet的写法就俩区别):
case R.id.button_volleyconnect:
StringRequest request=new StringRequest(Request.Method.POST,//用post方法,url是服务器地址
"http://192.168.0.36:8080/RandomService/JDBCServlet",
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
mTextview_show.setText(response);//连接URL
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
mTextview_show.setText("无网络连接");//error
}
}){//这是继承onResponse的匿名内部类,复写这个方法,往服务器发送的数据写在Map中
@Override
protected Map<String, String> getParams() throws AuthFailureError {
HashMap<String,String> map=new HashMap<>();
map.put("username","zhangsan");
return map;
}
};
MySingleton.getInstance(getApplicationContext()).addToRequestQueue(request);
break;