android 大图片在listview中内存溢出的问题
在listview中有很多时候,都因为图片太大造成内存溢出的问题,下面这个demo用10M大小的图片测试并没有出现内存溢出和卡顿现象。
项目截图
主要代码:
package com.example.listview; import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.widget.ListView; public class MainActivity extends Activity { ListAdapter mAdapter; ListView mListView; int count = 100; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mListView = (ListView) findViewById(R.id.listView1); mAdapter = new ListAdapter(this,mListView); mAdapter.setData(count); mListView.setAdapter(mAdapter); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.activity_main, menu); return true; } }
adapter:
package com.example.listview; import java.util.ArrayList; import android.content.Context; import android.graphics.Bitmap; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.ListView; public class ListAdapter extends BaseAdapter { int mData; Context mContext; ListView mListView; SyncImageLoader mSyncImageLoader; ArrayList<String> mlist; public ListAdapter(Context context,ListView listView) { super(); this.mContext = context; this.mListView=listView; this.mListView.setOnScrollListener(onScrollListener); mSyncImageLoader=new SyncImageLoader(); mlist=new ArrayList<String>(); } public void setData(int data) { this.mData = data; } @Override public int getCount() { // TODO Auto-generated method stub return mData; } @Override public Object getItem(int arg0) { // TODO Auto-generated method stub return arg0; } @Override public long getItemId(int arg0) { // TODO Auto-generated method stub return arg0; } @Override public View getView(int position, View convertView, ViewGroup arg2) { ViewHolder holder = null; if (convertView == null) { holder = new ViewHolder(); LayoutInflater inflater = LayoutInflater.from(mContext); convertView = inflater.inflate(R.layout.list_item, null); holder.iv01 = (ImageView) convertView.findViewById(R.id.imageView1); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.iv01.setId(0x7f021000+position); if(mlist.contains("/sdcard/pic_01.jpg")){ holder.iv01.setImageBitmap(MyBitmap.readBitMap("/sdcard/pic_01.jpg"+"1.jpg",1)); }else{ holder.iv01 .setImageBitmap(MyBitmap.readBitMap(mContext, R.drawable.load)); mSyncImageLoader.loadImage(position, "/sdcard/pic_01.jpg", imageLoadListener); mlist.add("/sdcard/pic_01.jpg"); } return convertView; } class ViewHolder { public ImageView iv01; } AbsListView.OnScrollListener onScrollListener = new AbsListView.OnScrollListener() { public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { } public void onScrollStateChanged(final AbsListView view, int scrollState) { //滑动的三种状态,当滑动停止之后加载图片 switch (scrollState) { case AbsListView.OnScrollListener.SCROLL_STATE_FLING: System.out.println("SCROLL_STATE_FLING"); mSyncImageLoader.lock(); break; case AbsListView.OnScrollListener.SCROLL_STATE_IDLE: System.out.println("SCROLL_STATE_IDLE"); loadImage(); break; case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL: System.out.println("SCROLL_STATE_TOUCH_SCROLL"); mSyncImageLoader.lock(); break; default: break; } } }; private void loadImage(){ int start = mListView.getFirstVisiblePosition(); int end = mListView.getLastVisiblePosition(); if (end >= getCount()) { end = getCount() - 1; } mSyncImageLoader.setLoadLimit(start, end); mSyncImageLoader.unlock(); } SyncImageLoader.OnImageLoadListener imageLoadListener = new SyncImageLoader.OnImageLoadListener() { public void OnImageLoad(Integer t, Bitmap bitmap) { ImageView iv01 =(ImageView) mListView.findViewById(0x7f021000+t); if(iv01 !=null){ iv01.setImageBitmap(bitmap); } } }; }
SyncImageLoader:
package com.example.listview; import java.util.ArrayList; import android.graphics.Bitmap; import android.os.Handler; public class SyncImageLoader { private Object lock = new Object(); // 是否允许加载图片 private boolean mAllowLoad = true; // 开始加载图片的位置 private int mStartLoadLimit = 0; // 停止加载图片的位置 private int mStopLoadLimit = 0; ArrayList<String> list=new ArrayList<String>(); Bitmap mBitmap; Handler handler = new Handler(); public interface OnImageLoadListener { public void OnImageLoad(Integer id, Bitmap bitmap); } public void setLoadLimit(int startLoadLimit, int stopLoadLimit) { mStartLoadLimit = startLoadLimit; mStopLoadLimit = stopLoadLimit; } public void lock() { mAllowLoad = false; } public void unlock() { mAllowLoad = true; synchronized (lock) { lock.notifyAll(); } } public void loadImage(Integer t, String imageUrl, OnImageLoadListener listener) { final OnImageLoadListener mListener = listener; final String mImageUrl = imageUrl; final Integer mt = t; new Thread(new Runnable() { public void run() { if (!mAllowLoad) { synchronized (lock) { try { lock.wait(); } catch (Exception e) { e.printStackTrace(); } } } if (mStopLoadLimit == 0 && mStartLoadLimit == 0) { loadImage(mImageUrl, mt, mListener); } if (mAllowLoad && mt <= mStopLoadLimit && mt >= mStartLoadLimit) { System.out.println("loadImage"); loadImage(mImageUrl, mt, mListener); } } }).start(); } private void loadImage(final String mImagePath, final Integer mt, final OnImageLoadListener mListener) { try { if(list.contains(mImagePath)){ mBitmap = MyBitmap.readBitMap(mImagePath + "1.jpg",1); }else{ mBitmap = MyBitmap.readBitMap(mImagePath,20); MyBitmap.saveFile(mBitmap, mImagePath + "1.jpg"); list.add(mImagePath); } handler.post(new Runnable() { public void run() { if (mAllowLoad) { mListener.OnImageLoad(mt, mBitmap); } } }); } catch (Exception e) { e.printStackTrace(); } } }
MyBitmap:
package com.example.listview; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; public class MyBitmap { public static Bitmap readBitMap(String fileName,int n) { BitmapFactory.Options opt = new BitmapFactory.Options(); opt.inPreferredConfig = Bitmap.Config.RGB_565; opt.inSampleSize = n; // width,hight设为原来的十分一 opt.inPurgeable = true; opt.inInputShareable = true; // 获取资源图片 FileInputStream fis = null; try { fis = new FileInputStream(fileName); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } return BitmapFactory.decodeStream(fis, null, opt); } public static Bitmap readBitMap(Context context, int resId) { BitmapFactory.Options opt = new BitmapFactory.Options(); opt.inPreferredConfig = Bitmap.Config.RGB_565; // opt.inSampleSize = 10; //width,hight设为原来的十分一 opt.inPurgeable = true; opt.inInputShareable = true; // 获取资源图片 InputStream is = context.getResources().openRawResource(resId); return BitmapFactory.decodeStream(is, null, opt); } public static void saveFile(Bitmap bm, String fileName) throws IOException { File myCaptureFile = new File(fileName); BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream(myCaptureFile)); bm.compress(Bitmap.CompressFormat.JPEG, 80, bos); bos.flush(); bos.close(); } }
csdn下载地址:http://download.csdn.net/detail/wenwei19861106/4865907