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

posted on 2012-12-09 21:28  南瓜饼  阅读(5183)  评论(3编辑  收藏  举报

导航