- Android Volley 是个什么玩意儿?
Android Volley 是Google在2013年的I/O大会上推出的一个新的网络通信框架。Volley可以说把异步网络通信和网络图片的加载都封装于一身,他让开发者们更轻松地进行HTTP通信和加载网络上的图片。Volley除了简单易用之外,在性能上也进行了大幅度的调整,它的设计目标就是非常适合进行数据量不大且通信频繁的网络操作,所以并不适合对大数据量的网络操作,比如下载文件。
Android Volley 要怎么用呢?
首先把Volley.jar导入我们的项目lib中,掉完之后,我们开始学习怎么使用它,在这里我进行:- 使用Volley实现JSON字段请求
- 使用Volley实现异步加载图片
- 使用Volley中封装的NetWorkImageView来实现异步加载图片
注意:在AndroidManifest.xml中加入网络权限。
- 使用Volley实现JSON字段请求
先不多说,直接上代码,然后再进行分析。(下面是有道字典的api)
// 1.使用Volley实现JSON字段请求
public void getJSONVolley(){
RequestQueue requestQueue = Volley.newRequestQueue(this);
String JSONDateUrl = " http://fanyi.youdao.com/openapi.do?keyfrom=1234567890qwe&key=869501308&type=data&doctype=json&version=1.1&q=good ";
//JsonObjectRequest(int method, String url, JSONObject jsonRequest, Listener<JSONObject> listener, ErrorListener errorListener)
//JsonObjectRequest(String url, JSONObject jsonRequest, Listener<JSONObject> listener, ErrorListener errorListener)
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET,JSONDateUrl, null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Log.e("response====>","请求成功");
((TextView)findViewById(R.id.textView)).setText(response.toString());
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
Log.e("volleyError====>","对不起,请求失败");
}
});
requestQueue.add(jsonObjectRequest);
}
第一步:创建RequestQueue对象
RequestQueue是啥?看它的英文顾名思义,它是请求队列的一个对象。它可以缓存所有的HTTP请求,然后按照一定的算法并发地发出这些请求。RequestQueue内部的设计就是非常适合高并发的,因此我们不必为每一次HTTP请求都创建一个RequestQueue对象,这是非常浪费资源的,基本上在每一个需要和网络交互的Activity中创建一个RequestQueue对象就足够了。
第二步:创建JsonObjectRequest请求
第一种:
public JsonObjectRequest(int method, String url, JSONObject jsonRequest, Listener listener, ErrorListener errorListener)
参数 method :是HTTP的请求类型,通常有Request.Method.GET和Request.Method.PSOT
参数 url :是网络请求的地址
参数 jsonRequest :是一个数据传输对象
参数 listener :是请求成功的监听器
参数 errorListener :是请求失败的监听器
第二种:
public JsonObjectRequest(String url, JSONObject jsonRequest, Listener listener, ErrorListener errorListener)第三步:JsonObjectRequest请求对象创建完毕之后放入RequestQueue队列中去就ok了。
运行结果如图所示:
- 网络请求需要传参怎么办?
上面说的是GET请求方法,接下来就来说说POST,一般项目中都是需要向借口传入好几个参数的,这个要怎么解决呢?
(在这里建议我们初学者使用StringRequset来进行请求网络,因为在传参是使用JsonObjectRequest会有坑。。。暂时先不研究这个。。。)
把参数method改为Request.Method.POST,并重写StringRequset中匿名内部类方法的getParams()方法。
// 1.使用Volley实现JSON字段请求
public void getJSONVolley(){
RequestQueue requestQueue = Volley.newRequestQueue(this);
String JSONDateUrl = " http://fanyi.youdao.com/openapi.do";
StringRequest stringRequest = new StringRequest(Request.Method.POST, JSONDateUrl,
new Response.Listener<String>() {
@Override
public void onResponse(String s) {
Log.e("response====>", "请求成功");
((TextView) findViewById(R.id.textView)).setText(s);
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
Log.e("volleyError====>","对不起,请求失败");
}
}){
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> map = new HashMap<String,String>();
map.put("keyfrom","1234567890qwe");
map.put("key","869501308");
map.put("type","data");
map.put("doctype","json");
map.put("version","1.1");
map.put("q","good");
return map;
}
};
requestQueue.add(stringRequest);
}
运行结果一样。
2.使用Volley实现异步加载图片
在布局文件中添加一个ImageView给一个id为imageView。
// 2.使用Volley实现异步加载图片
public void loadImageView(){
//百度上随便找的图片
String imageURL = "http://img4.duitang.com/uploads/item/201406/20/20140620155726_ch85t.thumb.700_0.jpeg";
RequestQueue requestQueue = Volley.newRequestQueue(this);
//设置缓存,20为占有的内存大小
final LruCache<String,Bitmap> lruCache = new LruCache<String,Bitmap>(20);
//设置照片的缓存,如果有缓冲就从缓存中获取图片
ImageLoader.ImageCache imageCache = new ImageLoader.ImageCache() {
@Override
public Bitmap getBitmap(String key) {
return lruCache.get(key);
}
@Override
public void putBitmap(String key, Bitmap value) {
lruCache.put(key,value);
}
};
ImageLoader imageLoader = new ImageLoader(requestQueue,imageCache);
//getImageListener方法第一个参数为你要加载图片的ImageView,第二个为默认图片,第三个为加载失败时显示的图片,可以为空
ImageLoader.ImageListener listener = imageLoader.getImageListener((ImageView)findViewById(R.id.imageView),
R.mipmap.ic_launcher,R.mipmap.ic_launcher);
imageLoader.get(imageURL,listener);
}
第一步:首先给我们的图片设置一个缓存
缓存在源码种叫做L1缓存,其实缓存分为L1,L2两种,L1就是所谓的内存缓存对象,将展示过的图片放入内存中进行缓存,L2就是磁盘混存,如果这个图片下载完成,它可以被存放在磁盘种,在没有网络的时候就可以被调出来使用了。
每次执行get方法(加载图片)时,Volley会到imageCache图片缓存对象中调用getBitmap(),看看有没有内存缓存,如果返回的是null,那么Volley就会从网络上下载,如果不为null,Volley会直接把取到的bitmap展示到imageView中。当图片展示到屏幕上后(无论图片是读取来的还是下载来的),Volley都会自动调用putBitmap把图片放入内存中缓存起来。第二步:加载图片
代码的思路是产生了imageLoader后,再初始化一个监听器,监听中传入ImageView对象、加载前的初始化图片、和加载失败后展示的图片,这个很好理解的。最后在imageLoader的get方法中传入URL和监听器来加载图片。
运行结果如下所示:
注意:get方法还有一种变体:
//imageLoader.get(imageURL,listener);
//imageLoader.get(imageURL,listener,0,0);
imageLoader.get(imageURL,listener,100,100);
这里最后传入的数值是得到图片的最大宽、高,注释掉的两个表是一个意思就是图片默认的宽高。
运行效果如下:
3.使用Volley中封装的NetWorkImageView来实现异步加载图片
首先布局文件的ImageView再也不是普通的ImageView而是:
<com.android.volley.toolbox.NetworkImageView
android:id="@+id/networkImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
其实NetWorkImageView的代码和上面的差不多,如下所示:
// 3.使用Volley中封装的NetWorkImageView来实现异步加载图片
public void loadNetworkImageView(){
String imageURL = "http://img4.duitang.com/uploads/item/201406/20/20140620155726_ch85t.thumb.700_0.jpeg";
RequestQueue requestQueue = Volley.newRequestQueue(this);
final LruCache<String,Bitmap> lruCache = new LruCache<String,Bitmap>(20);
ImageLoader.ImageCache imageCache = new ImageLoader.ImageCache() {
@Override
public Bitmap getBitmap(String key) {
return lruCache.get(key);
}
@Override
public void putBitmap(String key, Bitmap value) {
lruCache.put(key,value);
}
};
ImageLoader imageLoader = new ImageLoader(requestQueue,imageCache);((NetworkImageView)findViewById(R.id.networkImageView)).setImageUrl(imageURL,imageLoader);
}
- 代码实现的步骤和上面的差不多,运行效果也是一样的,但是NetworkImageView没有提供任何设置图片等宽高方法,这由于它是一个控件,在加载图片的时候他会自动获取自身的宽高,然后对比网络图片的宽高,再决定是否需要对图片进行压缩。也就是说,压缩过程是在内部完全自动化的,并不需要我们关心。NetworkImageView最终会始终呈现给我们一张大小比控件尺寸略大的网络图片,因为它会根据控件宽高等比缩放原始图片。如果不想对图片进行压缩,那么把宽高都设置为自适应,那么就不会有任何压缩了。