上一篇介绍了如何用volley来创建获取JSON,上一篇的地址在
http://blog.csdn.net/linshijun33/article/details/47954693
这一篇就来介绍一下如何利用Volley来加载图片。
/** * 利用Volley异步加载图片 * * 注意方法参数: * getImageListener(ImageView view, int defaultImageResId, int errorImageResId) * 第一个参数:显示图片的ImageView * 第二个参数:默认显示的图片资源 * 第三个参数:加载错误时显示的图片资源,可设置为空 */
private void loadImageByVolley() {
String imageUrl="http://my.csdn.net/uploads/avatar/1/1/1/1_linshijun33.jpg";
RequestQueue requestQueue = Volley.newRequestQueue(this);
//利用lrucache缓存图片,提高加载速度
final LruCache<String, Bitmap> lruCache = new LruCache<String, Bitmap>(20);
ImageLoader.ImageCache imageCache = new ImageLoader.ImageCache() {
@Override
public void putBitmap(String key, Bitmap value) {
lruCache.put(key, value);
}
@Override
public Bitmap getBitmap(String key) {
return lruCache.get(key);
}
};
ImageLoader imageLoader = new ImageLoader(requestQueue, imageCache);
ImageLoader.ImageListener listener = ImageLoader.getImageListener(volleyImageView, R.mipmap.ic_launcher,R.mipmap.ic_launcher);
imageLoader.get(imageUrl, listener);
}
/** * 利用NetworkImageView显示网络图片 */
private void showImageByNetworkImageView() {
String imageUrl="http://my.csdn.net/uploads/avatar/1/1/1/1_linshijun33.jpg";
RequestQueue requestQueue = Volley.newRequestQueue(this);
//利用lrucache缓存图片,提高加载速度
final LruCache<String, Bitmap> lruCache = new LruCache<String, Bitmap>(20);
//ImageCache图片缓存,可以实现瀑布流
ImageLoader.ImageCache imageCache = new ImageLoader.ImageCache() {
@Override
public void putBitmap(String key, Bitmap value) {
lruCache.put(key, value);
}
@Override
public Bitmap getBitmap(String key) {
return lruCache.get(key);
}
};
ImageLoader imageLoader = new ImageLoader(requestQueue, imageCache);
mNetworkImageView.setTag("url");//设置tag
mNetworkImageView.setImageUrl(imageUrl,imageLoader);
}
具体用法也比较简单,将这两个方法直接添加到OnCreat( )中就可以了。
对比这两种方式,其实还是非常接近的。整理了一下基本的流程就是:
创建请求队列—–>实例化一个LruCache缓存类——>设置ImageCache图片缓存——>运用到ImageLoader中—–>一个设置listener用get方式得到 ,另一个setImageUrl得到
ImageLoader也可以用于加载网络上的图片,并且它的内部也是使用ImageRequest来实现的,不过ImageLoader明显要比ImageRequest更加高效,因为它不仅可以帮我们对图片进行缓存,还可以过滤掉重复的链接,避免重复发送请求。
由于ImageLoader已经不是继承自Request的了,所以它的用法也和我们之前学到的内容有所不同,总结起来大致可以分为以下四步:
创建一个RequestQueue对象。
创建一个ImageLoader对象。
获取一个ImageListener对象。
调用ImageLoader的get()方法加载网络上的图片。
主要的使用方法如下,完全按照上面4个步骤来进行的。其中BitmapCache是一个自建的缓存类。可以参考源码。
/** * 使用imageLoader来加载图片 */
private void showByImageLoaader() {
String imageUrl="http://my.csdn.net/uploads/avatar/1/1/1/1_linshijun33.jpg";
//创建请求队列
RequestQueue requestQueue = Volley.newRequestQueue(this);
//新建imageLoader对象,第一个参数为队列,第二个参数为高效缓存类BitmapCache
ImageLoader imageLoader=new ImageLoader(requestQueue,new BitmapCache());
//用loader.getlistener方法来设置listener
ImageLoader.ImageListener listener=imageLoader.getImageListener(mImageLoaderView,//要设置图片的view
R.drawable.abc_cab_background_top_mtrl_alpha,//下载还未完成时显示的默认图片
R.drawable.abc_ic_menu_share_mtrl_alpha); //下载失败显示的图片
//通过get方法加载图片
imageLoader.get(imageUrl,listener);
}
效果图大概就是这样,上面三张图片以及前面文章提过的文本折叠
需要源码的朋友可以到我的资源那里下载。
http://download.csdn.net/detail/linshijun33/9067619
这里插播解释下LruCache:
此类在android-support-v4的包中提供,非常适合用来缓存图片,它的主要算法原理是把最近使用的对象用强引用存储在 LinkedHashMap 中,并且把最近最少使用的对象在缓存值达到预设定值之前从内存中移除。在图片较大而且较多的情况下,为防止内存溢出(out of memery即OOM),通常都要使用类似的缓存。
ps:今年阿里校招笔试就考了LFU高级缓存。都属于算法类型的,感兴趣的可以去了解下。应用方面,这两位大神的博客可以去看下,夏神和郭神
http://blog.csdn.net/xiaanming/article/details/9825113
http://blog.csdn.net/guolin_blog/article/details/9526203
以及ImageCache实现瀑布流
http://blog.csdn.net/puhaibo_skynet/article/details/39186287
目前项目需要用到的就这些了,Volley也是比较简单易用的,上篇就说过易用到能够举一反三的。
刚才也找到一篇学习笔记,写得也很详细,分享下。
http://www.aiuxian.com/article/p-84125.html
主要的部分挑选出来了,大家可以看下,感谢上面的博主。
public class MyVolley extends Activity implements OnClickListener{
private Button bt_json, bt_image, bt_netimage, bt_imageloder;
private ImageView iv_volley;
private TextView tv_volley;
private NetworkImageView netIV_volley;
private String jsonObject="{'name':'llb','age':'20'}";
private JSONObject jsonUp;//要上传的JSONObject
private RequestQueue queue;
private String jsonUrl = "http://218.192.170.251:8080/AndroidServerDemo/LoginServlet";
//上面这个jsonUrl是自己随便写的服务器端,只完成简单的json数据交互
private String imageUrl1 = "http://img1.27.cn/images/201011/04/1288857805_42835600.jpg";
private String imageUrl2 = "http://img.cf8.com.cn/uploadfile/2011/1031/20111031100803979.jpg";
private String imageUrl3 = "http://img.pconline.com.cn/images/upload/upc/tx/wallpaper/1209/07/c1/13698570_1347000164468_320x480.png";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_myvolley);
initView();
}
/** * 初始化各个控件 */
private void initView() {
bt_json = (Button) findViewById(R.id.bt_json);
bt_image = (Button) findViewById(R.id.bt_image);
bt_netimage = (Button) findViewById(R.id.bt_netimage);
bt_imageloder = (Button) findViewById(R.id.bt_imageloder);
iv_volley = (ImageView) findViewById(R.id.iv_volley);
tv_volley = (TextView) findViewById(R.id.tv_volley);
netIV_volley = (NetworkImageView) findViewById(R.id.netIV_volley);
queue = Volley.newRequestQueue(this);// 获取一个请求队列对象
bt_json.setOnClickListener(this);//按钮点击事件监听
bt_image.setOnClickListener(this);
bt_netimage.setOnClickListener(this);
bt_imageloder.setOnClickListener(this);
}
/** * 请求json数据 */
private void requestJsonObject() {
Log.i("llb", "requestJsonObject()");
try {
jsonUp=new JSONObject(jsonObject);
} catch (JSONException e) {
e.printStackTrace();
}
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(
Method.POST, jsonUrl,jsonUp, new Listener<JSONObject>() {
@Override
public void onResponse(JSONObject arg0) {
Log.i("llb", "onResponse(JSONObject)");
String json = arg0.toString();
tv_volley.setText("服务器返回的json数据:"+json); }
}, new ErrorListener() {
@Override
public void onErrorResponse(VolleyError arg0) {
Log.i("llb", "onErrorResponse:"+arg0.getMessage());
tv_volley.setText("服务器请求失败:"+arg0.getMessage());
}
});// 也可以在这里携带需要上传的数据
Log.i("llb", "jsonUp"+jsonUp.toString());
queue.add(jsonObjectRequest);// 添加请求到队列里
}
private void requestByImageRequest() {
Log.i("llb", "requestImage()");
// 请求方法1:ImageRequest能够处理单张图片,返回bitmap。
ImageRequest imageRequest = new ImageRequest(imageUrl1,
new Listener<Bitmap>() {
@Override
public void onResponse(Bitmap response) {
Log.i("llb","bitmap height"+response.getHeight()+"&width="+response.getWidth());
iv_volley.setImageBitmap(response);// 显示图片
}
}, 200, 200, Config.ARGB_8888, new ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MyVolley.this, "请求图片失败了", 0).show();
}
});
// ImageRequest中已经写好了缓存,直接用就好了,使用的是DiskBasedCache
//测试发现直接把大图放到了下面的路径里,上面仅仅是改变了显示时的大小,
//缓存图片大小并无变化,不解??
imageRequest.shouldCache();// 缓存文件在/data/data/包名/cache/volley
queue.add(imageRequest);// 把请求加入到队列里面
}
private void requestByImageLoader() {
// 方法二:利用ImageLoader
ImageListener listener = ImageLoader.getImageListener(iv_volley,
R.drawable.ic_launcher, R.drawable.error);
//缓存文件也放在/data/data/包名/cache/volley,缓存图片大小并无变化
ImageLoader loader = new ImageLoader(queue, new MyImageCache(5 * 1024 * 1024));
loader.get(imageUrl2, listener, 300, 300);// 获取图片
//最后还是调用ImageRequest里面的doParse()函数去请求网络
}
private void requestByNetworkImageView() {
// 方法三:利用NetworkImageView来请求图片
ImageLoader imageLoader = new ImageLoader(queue, new MyImageCache(5 * 1024 * 1024));
netIV_volley.setDefaultImageResId(R.drawable.ic_launcher);//默认图片
netIV_volley.setErrorImageResId(R.drawable.error);//出错时的图片
// public ImageContainer get(String requestUrl, final ImageListener listener) {
// return get(requestUrl, listener, 0, 0);
// }最后事实上调用的是上面这个ImageLoader里面的这个函数,而且是默认尺寸,算是一个缺陷???
netIV_volley.setImageUrl(imageUrl3, imageLoader);//请求图片
}
@Override
public void onClick(View v) { // 按钮响应
switch (v.getId()) {
case R.id.bt_json:// 请求json
requestJsonObject();
break;
case R.id.bt_image:// 利用ImageRequest请求图片
requestByImageRequest();
break;
case R.id.bt_imageloder:// 利用ImageLoader请求图片
requestByImageLoader();
break;
case R.id.bt_netimage:
requestByNetworkImageView();
break;
}
}
}
需要源码的朋友可以到我的资源那里下载。
http://download.csdn.net/detail/linshijun33/9067619
在此感叹一句:
信息时代,做一个乐于学习,乐于分享的人,才不会落后。
有时间再去研究鸿洋大神的Volley源码分析:
http://blog.csdn.net/lmj623565791/article/details/47721631