参考:http://www.kwstu.com/ArticleView/kwstu_20144118313429
1.概述:
如今,android应用不可避免会用到网络技术,而常用的就是HttpURLConnection和HttpClient。
但HttpURLConnection和HttpClient的用法还是稍微有些复杂的,如果不进行适当封装的话,很容易就会写出不少重复代码。于是乎,一些Android网络通信框架也就应运而生,比如说AsyncHttpClient,它把HTTP所有的通信细节全部封装在了内部,我们只需要简单调用几行代码就可以完成通信操作了。再比如Universal-Image-Loader,它使得在界面上显示网络图片的操作变得极度简单,开发者不用关心如何从网络上获取图片,也不用关心开启线程、回收图片资源等细节,Universal-Image-Loader已经把一切都做好了。
Android开发团队也是意识到了有必要将HTTP的通信操作再进行简单化,于是在2013年Google I/O大会上推出了一个新的网络通信框架——Volley。Volley可是说是把AsyncHttpClient和Universal-Image-Loader的优点集于了一身。
想要详细了解volley可以,查看源码包:
volley源码包
2.原理:
不用再自己创建线程,本身存在线程池。
其中蓝色的是主线程,绿色的是缓存线程,黄色的是网络线程
1.当一个Request请求添加到RequestQueue请求队列中,Volley就开始工作了。RequestQueue请求队列中持有一个CacheDispatcher缓存管家和一组NetworkDispatcher网络管家。
2.RequestQueue会先叫来CacheDispatcher缓存管家,让他去看看,当前请求的数据在没在cache中。
2.1.当前的数据在cache中,那就把数据从cache中取出来,然后经过一番加工,将加工好的数据交付给主线程
2.2.当前数据没在cache中,进行第3步
3.进行到了这一步,那肯定是数据没有在缓存中,那只能去网络中获取了,这时候RequestQueue会叫来NetworkDispatcher,NetworkDispatcher可是有一帮呢,其实这是一个线程池,默认情况下会启动4个线程去网络下载数据。所以RequestQueue把当前闲着的NetworkDispatcher叫来,给他们分配任务。
4.拿到任务的NetworkDispatcher就会去网络上下载数据了,与此同时,他会判断下载到的数据能否写入到cache缓存中,如果可以的话就写入cache,以便于下一次直接从cache中获取到数据。最后,将数据加工,交付给主线程。
3.用法:
1)下载Volley:
- eclipse:下载jar包,复制到工程下的libs中即可。
- studio:
法1:和eclipse一样把jar包放在libs下
法2:用studio直接下载:右击项目>open moudle settings>在Dependencies中搜索:volley,使用最新的版本,OK即可。
法3:导入源码包:file>右击import module >找到源码包路径>确定。 还需要导入module,在Dependencies>点击+号导入modul
stdio中导包的这种方式,也可以用来导入httpclient包,因为在android6.0中舍弃了httpclient,可以在6.0搜索:org.apache.http导入httpclient包即可。
2)使用步骤:
- 创建请求队列:
RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
- 创建http请求:
//可以传入三个参数或四个参数(请求方式,url,请求成功的监听,请求错误的监听)
StringRequest request = new StringRequest(,,,);
- 将请求添加到请求队列中:
queue.add(request);
- 不要忘了,这里连接网络需要权限:
<uses-permission android:name="android.permission.INTERNET"/>
4.范例:
功能:连接百度网页,将返回信息显示到textview中。
5.改进:采用单例模式
我们使用Volley是由于它不像Httpclient或其他网络连接那样,每次点击都会创建一个线程,但现在的问题是:每次点击都会创建一个请求队列。
这不是我们想要的效果,所以这里采用单例的方式使一个应用程序只有一个请求队列。至于单例的类,android的API中也给出了,这里我们列出来,以后可以直接使用即可。
1)单例请求队列的类:
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;
/**
* Created by zhonghangIT on 2015/9/14.
*/
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;
}
}
2)volley单例时的使用:
3)权限:
<uses-permission android:name="android.permission.INTERNET"/>
6.Volley中自带的Network ImageView(下载图片)
Network ImageView方法获得图片的方法,现在都一般不用,一般采用ImageLoader的方式。
1)xml布局中的图片要用Network ImageView:
<com.android.volley.toolbox.NetworkImageView
android:id="@+id/netimageview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
</com.android.volley.toolbox.NetworkImageView>
2)Network ImageView的使用(采用单例)
networkImageView.setImageUrl("http://adress of img",MySingleton.getInstance(this).getImageLoader());//获得指定url图片