转载自 http://blog.csdn.net/guolin_blog/article/details/9526203
由于每个android应用程序都有内存限制,所以如果加载很多图片的话,一定会出现OOM异常
这就需要使用LruCache内存缓存技术了,LruCache是在support-v4 jar包中,所以想运用此技术需要把jar包加进去。
LruCache的技术原理就是吧最近使用的对象使用强引用保存在LinkedHashMap中,对那些很少使用的在缓存值达到预定值之前从内存中移除
以前经常使用的软引用 在2.3之后已经不再推荐使用了,因为android的垃圾回收机制更倾向于软引用的回收,使得这种技术不再变得可考
package com.qunzheng.photowalldemo; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.AsyncTask; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.ArrayAdapter; import android.widget.GridView; import android.widget.ImageView; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.ArrayList; import java.util.List; /** * Created by QunZheng on 2015/5/17. */ public class PhotoWallAdapter extends ArrayAdapter implements AbsListView.OnScrollListener { private static final String TAG = "PhotoWallAdapter"; private GridView mPhotoWall; //定义内存缓存 private MyLruCache memoryCache; private List<DownloadBitmapTask> tasks; private int firstVisibleItem; private int visibleItemCount; private boolean firstLoad = true; public PhotoWallAdapter(Context context, int resource, String[] objects, GridView mPhotoWall) { super(context, resource, objects); //获取应用程序的最大可用内存,并且分配1/8的内存给memoryCache long maxMemory = Runtime.getRuntime().maxMemory(); memoryCache = new MyLruCache((int)(maxMemory / 8)); tasks = new ArrayList<>(); this.mPhotoWall = mPhotoWall; //设置照片的墙的滚动监听事件 this.mPhotoWall.setOnScrollListener(this); } @Override public View getView(int position, View convertView, ViewGroup parent) { String imageUrl = (String) getItem(position); View view = null; if (convertView == null) { view = View.inflate(getContext(), R.layout.griditem_photo_wall, null); } else { view = convertView; } ImageView imageView = (ImageView) view.findViewById(R.id.photo); imageView.setTag(imageUrl); setImageView(imageView,imageUrl); return view; } private void setImageView(ImageView imageView, String imageUrl) { Bitmap bitmap = memoryCache.getBitmapFromMemoryCache(imageUrl); if (bitmap == null) { imageView.setImageResource(R.drawable.empty_photo); }else{ imageView.setImageBitmap(bitmap); } } private void loadBitmap(int firstVisibleItem, int visibleItemCount) { for (int i = firstVisibleItem; i < firstVisibleItem + visibleItemCount; i++) { String imageUrl = Images.imageThumbUrls[i]; ImageView imageView = (ImageView) mPhotoWall.findViewWithTag(imageUrl); Bitmap bitmap = memoryCache.getBitmapFromMemoryCache(imageUrl); if (bitmap == null) { //开启后台下载任务 DownloadBitmapTask task = new DownloadBitmapTask(); tasks.add(task); task.execute(imageUrl); }else { imageView.setImageBitmap(bitmap); } } } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { Log.i(TAG, "滚动条的状态发生改变:" + scrollState); if (scrollState == SCROLL_STATE_IDLE) { //加载图片 loadBitmap(firstVisibleItem, visibleItemCount); } else { cancleTasks(); } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { this.firstVisibleItem = firstVisibleItem; this.visibleItemCount = visibleItemCount; if (firstLoad && visibleItemCount > 0) { loadBitmap(firstVisibleItem,visibleItemCount); firstLoad = false; } Log.i(TAG,"firstVisibleItem:" + firstVisibleItem); Log.i(TAG,"visibleItemCount:" + visibleItemCount); } /** * */ public void cancleTasks() { if (tasks != null) { for (DownloadBitmapTask task : tasks) { task.cancel(false); } } } /** * 下载图片的任务 */ private class DownloadBitmapTask extends AsyncTask<String,Void,Bitmap>{ String imageUrl; @Override protected Bitmap doInBackground(String... params) { imageUrl = params[0]; Bitmap bitmap = downloadBitmap(imageUrl); Log.i(TAG, bitmap.toString()); if(bitmap != null){ //吧下载的bitmap添加到内存缓存中 memoryCache.addBitmapToMemoryCache(imageUrl,bitmap); } return bitmap; } @Override protected void onPostExecute(Bitmap bitmap) { ImageView imageView = (ImageView) mPhotoWall.findViewWithTag(imageUrl); if (imageView != null && bitmap != null) { imageView.setImageBitmap(bitmap); } tasks.remove(this); } private Bitmap downloadBitmap(String imageUrl) { HttpURLConnection conn = null; Bitmap bitmap = null; try { URL url = new URL(imageUrl); conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(5 * 1000); conn.setReadTimeout(5 * 1000); // conn.connect(); InputStream in = conn.getInputStream(); bitmap = BitmapFactory.decodeStream(in); } catch (Exception e) { e.printStackTrace(); }finally { if (conn != null) { conn.disconnect(); } } return bitmap; } } }