弄明白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 {
@Override
public 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);
}

@Override
protected int sizeOf(String key, Bitmap bitmap) {
return bitmap.getRowBytes() * bitmap.getHeight();
}

@Override
public Bitmap getBitmap(String url) {
return get(url);
}

@Override
public 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下载

时间: 2024-08-06 09:56:21

弄明白android网络库之Volley listView加载大量图片的相关文章

弄明白android 网络库之Volley

1.Volley是什么? Volley是Google 官方在2013 Android IO大会上推出的新网络通信框架, 一个使得android 网络通信更加容易并且迅速的HTTP库.它并且可以通过开放的AOSP仓库进行使用. 它有以下特性: (1)自动调度网络请求: (2)支持多并发的网络连接: (3)磁盘和内存响应缓存使用标准HTTP缓存特性: (4)支持请求优先级: (5)取消请求API.你可以取消一个请求,或者你可以设定块或取消的请求范围: (6)易于定制,例如,重试和补偿: (7)强大的

[Android学习系列16]Android把php输出的json加载到listview

首先写个php脚本输出json,注意,还要输出回车,方便android的bufferreader读取一行 <?php class Book { public $bookid; public $bookname; public $bookinfo; function __construct($id,$name,$info ){ $this->bookid = $id; $this->bookname = $name; $this->bookinfo = $info; } } $boo

Android利用Volley异步加载数据完整详细示例(二)

MainActivity如下: package cc.y; import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.os.Bundle; import android.util.LruCache; import android.widget.ImageView;

Android利用Volley异步加载数据完整详细示例(一)

MainActivity如下: package cc.cn; import java.util.HashMap; import org.json.JSONObject; import android.app.Activity; import android.content.Context; import android.os.Bundle; import com.android.volley.AuthFailureError; import com.android.volley.RequestQ

Android ListView加载更多

先看效果: ListView的footer布局: <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap

Android listview 加载更多定位问题

我们用Android在做Listview加载更多数据时,如果每次都重新new Adapter的话,视图就会滑动到第一条. 后来我发现listview有一个方法可以获取最顶部时哪一个 int  position = mListView.getFirstVisiblePosition(); 这样就可以获取目前显示的第一行到底是多少条. 于是我有找到一个方法,加载更多数据后.我们设置一下他的选取位置,就不会有滚动到第一个条了 mListView.setSelection(position); 但是仔细

【Android笔记】listview加载性能优化及有多种listitem布局处理方式

在android开发中Listview是一个很重要的组件,它以列表的形式根据数据的长自适应展示具体内容. 用户可以自由的定义listview每一列的布局,但当listview有大量的数据需要加载的时候,会占据大量内存,影响性能,这时候就需要按需填充并重新使用view来减少对象的创建. ListView加载数据都是在 1 public View getView(int position, View convertView, ViewGroup parent) { 2 3 ...... 4 5 }

Android利用Volley异步加载数据(JSON和图片)完整示例

Android利用Volley异步加载数据(JSON和图片)完整示例 MainActivity.java package cc.testvolley; import org.json.JSONObject; import android.app.Activity; import android.app.ProgressDialog; import android.graphics.Bitmap; import android.os.Bundle; import android.support.v

Android错误之ListView加载错位_ListView图片错位

又遇到ListView加载item时,多个item中的图片会错位的情况 现象如下图,同一个人的头像显示的乱七八糟 找了一张图,很好地说明了问题的原因 问题原因就在于convertView的重用,当重用 convertView 时,最初一屏显示 7 条记录, getView 被调用 7 次,创建了 7 个 convertView, 当 Item1 划出屏幕, Item8 进入屏幕时,这时没有为 Item8 创建新的 view 实例, Item8 复用的是Item1时候创建的view, Item8