当前位置: 代码迷 >> Android >> 搞明白android网络库之Volley listView加载大量图片
  详细解决方案

搞明白android网络库之Volley listView加载大量图片

热度:98   发布时间:2016-04-28 03:04:47.0
弄明白android网络库之Volley listView加载大量图片

一、加载一张图片

 

Volley是通过ImageRequest来获取网络上的图片的,指定一个URL,返回一个已经编码号的bitmap。当然它也提供了其他便利特性,比如调整图片大小。使用它它主要的好处是 Volley的计划线程确保了如图片编码、调整大小等昂贵的操作自动地在一个工作线程完成,不会给主线程带来太多的麻烦和干扰。

 

a cannedrequest for getting an image at a given URL and calling back with a decodedbitmap. It also provides convenience features like specifying a size to resizeto. Its main benefit is that Volley's thread scheduling ensures that expensiveimage operations (decoding, resizing) automatically happen on a worker thread.


1)初始化一个请求队列,最好写在application(记得在manifest里修改application)里,如此一开始就启动了。

public class VolleyApplication extends Application {@Overridepublic void onCreate() { super.onCreate();RequestManager.initVolley(this);}}

这里的RequestManager是我自定义的请求管理类,专门用来管理请求的。里面就有一个请求队列,然后在初始化方法里实例化。

private static RequestQueue mRequestQueue;public RequestManager() {// TODO Auto-generated constructor stub} public static void initVolley(Context context){mRequestQueue = Volley.newRequestQueue(context);}

2)然后编写图片请求

//Retrieves an image specified by the URL, displays it in the UI. request = new ImageRequest(url, new Response.Listener<Bitmap>() {             @Override             public void onResponse(Bitmap response) {                     singleImageView.setImageBitmap(response);             }         }, 0, 0, null,    new Response.ErrorListener() {        public void onErrorResponse(VolleyError error) {            Toast.makeText(ImageActivity.this, "download image error", Toast.LENGTH_LONG).show();        }    })

3)执行这个加载图片的请求:

RequestManager.addRequest(request);

4)在manifest中添加网络访问的权限。

 <uses-permission android:name="android.permission.INTERNET" />

当点击下载一张大图片的时候,瞬间就打印下面的内存不足的警告了。


因此多张图片下载就不能多次重复上次操作了。得使用ImageLoader。看第二点


二、多张图片下载

通过实例化一个ImageRequest可以下载到一张图片,问题是如果多张图片呢?还是这么玩么?你可以看到一张就出现内存不足,那么多张必然出现OOM。因此,Volley提供了ImageLoader and NetworkImageView 来下载大量图片,比如listview中。

 

1)建立内存缓存,android提供内存缓存类库,LruCache;注意还有一个类提供了LruCache,但是我们需要的是android.support.v4.util.LruCache

新建一个类继承自 LruCache类,并实现 ImageCache接口。

import android.graphics.Bitmap;import android.support.v4.util.LruCache;import com.android.volley.toolbox.ImageLoader;public class BitmapLruCache extends LruCache<String, Bitmap> implements ImageLoader.ImageCache{public BitmapLruCache(int maxSize) {super(maxSize);} @Overrideprotected int sizeOf(String key, Bitmap bitmap) {return bitmap.getRowBytes() * bitmap.getHeight();} @Overridepublic Bitmap getBitmap(String url) {return get(url);} @Overridepublic void putBitmap(String url, Bitmap bitmap) {put(url, bitmap);}}

2)实例化ImageLoader

android系统给每个应用程序分配的内存大小是不一样的。通过 Runtime.getRuntime().maxMemory()或者

((ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE))

.getMemoryClass();

 可以获得被分配的具体最大内存是多少。注意到两个单位是不一样的。

      private static ImageLoader mImageLoader;               //get the app's available memory  given by system,note that its unit is MB int memClass = ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass(); //or you can get the memory value by this//memClass = (int) Runtime.getRuntime().maxMemory() ;// Use 1/8th of the available memory for this memory cache.int cacheSize = 1024 * 1024 * memClass /4;mImageLoader = new ImageLoader(mRequestQueue, new BitmapLruCache(cacheSize)); /** * get imageLoader */public static ImageLoader getImageLoader(){if(mImageLoader != null){return mImageLoader;}else{throw new IllegalStateException("the ImageLoader is null and not be initialized! ");}}

3)在Adapter中通过NetworkImageView setImageUrl方法加载ImageLoader下载URL指定的图片。

holder.showImage.setImageUrl(imageArrayList.get(position), imageLoader);


注意一点,就是由于普通imageview中没有使用 ImageLoader的方法,因此必须使用 Volley开发的继承自 ImageView的子类NetworkImageView才能使用。


效果图如下:




测试Demo下载



  相关解决方案