android显示图片内存溢出有关问题

android显示图片内存溢出问题最近在做一个应用,要循环显示图片,可是图片很大,每个5M左右,如果按图片原来大

android显示图片内存溢出问题
最近在做一个应用,要循环显示图片,可是图片很大,每个5M左右,如果按图片原来大小显示,在显示两个图片之后必会内存溢出,谁能给个图片压缩显示方法,谢谢!!!

[解决办法]
........5M
这个就算recycle也没用了...
我觉得你可以这样,创建一张全局的bitmap(当然要按最大的创建),然后每个图片读取都按照字节的方式读出来,之后set个体这个全局的bitmap,显示的时候就显示这个全局的,一个用完就清空一下,在读取另一张,这样保证只有一个bitmap在占用内存....
[解决办法]
我有图片压缩的一个类你看看哈:

Java code
import com.xmobileapp.pictureviewer.R;import android.app.Activity;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.BlurMaskFilter;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Rect;import android.graphics.drawable.Drawable;import android.os.Bundle;import android.os.Handler;import android.util.AttributeSet;import android.view.GestureDetector;import android.view.KeyEvent;import android.view.MotionEvent;import android.view.View;import android.view.Window;import android.view.GestureDetector.SimpleOnGestureListener;import android.widget.Scroller;public class PictureShow extends Activity {    private PictureShowUtils mAllImages = new PictureShowUtils();    boolean mLayoutComplete;    boolean mPausing = false;    PictureSlideView mPictureSlideView;    /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);        setContentView(R.layout.main);        mPictureSlideView = (PictureSlideView) findViewById(R.id.grid);        mPictureSlideView.requestFocus();    }    @Override    public boolean onKeyUp(int keyCode, KeyEvent event) {        return super.onKeyUp(keyCode, event);    }    @Override    public boolean onKeyDown(int keyCode, KeyEvent event) {        int sel = mPictureSlideView.mSelImageIndex;        int count = mAllImages.getCount();        switch (keyCode) {        case KeyEvent.KEYCODE_DPAD_UP:            if (sel >= 1) {                sel--;                mPictureSlideView.ScrollUp();            }            break;        case KeyEvent.KEYCODE_DPAD_DOWN:            if (sel < count - 1) {                sel++;                mPictureSlideView.scrollDown();            }            break;        default:            break;        }        mPictureSlideView.mSelImageIndex = sel;        mPictureSlideView.mImageBlockManager.loadSelBlock(sel);        mPictureSlideView.invalidate();        return super.onKeyDown(keyCode, event);    }    @Override    public void onPause() {        super.onPause();        mPausing = true;    }    @Override    public void onResume() {        super.onResume();        mPausing = false;    }        public static class PictureSlideView extends View {        // 布局信息        class LayoutSpec {            LayoutSpec(int cols, int w, int h, int leftEdgePadding,                    int rightEdgePadding, int intercellSpacing) {                mColumns = cols;                mCellWidth = w;                mCellHeight = h;                mLeftEdgePadding = leftEdgePadding;                mRightEdgePadding = rightEdgePadding;                mCellSpacing = intercellSpacing;            }            int mColumns;            int mCellWidth, mCellHeight;            int mLeftEdgePadding, mRightEdgePadding;            int mCellSpacing;        };        private class ImageBlockManager {            private int mBlockCacheFirstBlockNumber = 0;            private int mBlockCacheStartOffset = 0;            //缩略图缓存            private ImageBlock[] mBlockCache;            //选定的缩略图对象            private ImageBlock mSelBlock;            //一屏上缩略图的行数            private static final int sRowsPerPage = 4;            //缩略图缓存大小参数            private static final int sPagesPreCache = 2;            private static final int sPagesPostCache = 2;            // 放大预览图的尺寸            private static final int sSelBlockWidth = 200;            private static final int sSelBlockHeight = 200;            private Bitmap mMissingImageThumbnailBitmap;            ImageBlockManager(Context context) {                mContext = context;                mBlockCache = new ImageBlock[sRowsPerPage * (sPagesPreCache + sPagesPostCache + 1)];                for (int i = 0; i < mBlockCache.length; i++) {                    mBlockCache[i] = new ImageBlock();                }                /* 读取图片 */                loadBlocks();                mSelBlock = new ImageBlock(sSelBlockWidth, sSelBlockHeight);            }            int blockHeight() {                return mCurrentSpec.mCellSpacing + mCurrentSpec.mCellHeight                        + mCurrentSpec.mCellSpacing;            }            int blockWidth() {                return mCurrentSpec.mCellSpacing + mCurrentSpec.mCellWidth                        + mCurrentSpec.mCellSpacing;            }            void loadSelBlock(int pos) {                mSelBlock.loadSelImage(pos);            }            private void paintSelBlock(Canvas canvas) {                int pos = mSelImageIndex;                if (pos < 0)                    return;                Bitmap b = mSelBlock.mBitmap;                if (b == null) {                    return;                }                int xPos = 0;                int yPos = 0;                yPos = mScrollY + mCurrentSpec.mCellSpacing;                xPos = mCurrentSpec.mCellWidth + mCurrentSpec.mLeftEdgePadding;                canvas.drawBitmap(b, xPos, yPos, mGridViewPaint);            }            // 获取代表“没有缩略图”的图片对象            public Bitmap getErrorBitmap() {                mMissingImageThumbnailBitmap = BitmapFactory.decodeResource(                        PictureSlideView.this.getResources(),                        R.drawable.nothumbnail);                return mMissingImageThumbnailBitmap;            } 


[解决办法]
接上

Java code
private void loadBlocks() {                ImageBlock[] blocks = mBlockCache;                int numBlocks = blocks.length;                int first = 0;                for (int i = 0; i < numBlocks; i++) {                    int j = first + i;                    if (j >= numBlocks)                        j -= numBlocks;                    ImageBlock b = blocks[j];                    b.mBlockNumber = j;                    if (b.loadBlock() == 0)                        break;                }            }            void doDraw(Canvas canvas) {                ImageBlockManager.ImageBlock[] blocks = mBlockCache;                if (blocks[0] == null) {                    return;                }                final int thisHeight = getHeight();                final int height = blocks[0].mBitmap.getHeight();                final int scrollPos = mScrollY;                int currentBlock = (scrollPos < 0) ? ((scrollPos - height + 1) / height)                        : (scrollPos / height);                while (true) {                    final int yPos = currentBlock * height;                    if (yPos >= scrollPos + thisHeight) {                        break;                    }                    int effectiveOffset = (mBlockCacheStartOffset + (currentBlock++ - mBlockCacheFirstBlockNumber))                            % blocks.length;                    ImageBlock block = blocks[effectiveOffset];                    if (block == null)                        break;                    Bitmap b = block.mBitmap;                    if (b == null) {                        break;                    }                    canvas.drawBitmap(b, 0, yPos, mGridViewPaint);                } // end of while                /* Paint Selection */                paintSelBlock(canvas);            }/* end of doDraw */            private class ImageBlock {                private static final int mBlurRadius = 5;                private static final int mBlockAlpha = 180;                private static final int mBorderAlpha = 180;                private static final int mSelBorderAlpha = 150;                Drawable mCellOutline;                Bitmap mBitmap;                Canvas mCanvas;                Paint mPaint = new Paint();                int mBlockNumber;                boolean mIsVisible;                ImageBlock() {                    mBitmap = Bitmap.createBitmap(getWidth(), blockHeight(),                            Bitmap.Config.ARGB_8888);                    mCanvas = new Canvas(mBitmap);                    mPaint.setTextSize(14F);                    mPaint.setStyle(Paint.Style.FILL);                    mPaint.setAlpha(mBlockAlpha);                    mBlockNumber = -1;                    mCellOutline = PictureSlideView.this.getResources()                            .getDrawable(android.R.drawable.gallery_thumb);                    mCellOutline.setAlpha(mBorderAlpha);                }                ImageBlock(int w, int h) {                    mBitmap = Bitmap                            .createBitmap(w, h, Bitmap.Config.ARGB_8888);                    mCanvas = new Canvas(mBitmap);                    mPaint.setTextSize(14F);                    mPaint.setStyle(Paint.Style.FILL);                    mPaint.setFilterBitmap(true);                    mPaint.setMaskFilter(new BlurMaskFilter(mBlurRadius,                            BlurMaskFilter.Blur.NORMAL));                    mBlockNumber = -1;                    mCellOutline = PictureSlideView.this.getResources()                            .getDrawable(android.R.drawable.gallery_thumb);                    mCellOutline.setAlpha(mSelBorderAlpha);                }                private int loadBlock() {                    int count = mGallery.mAllImages.getCount();                    int base = (mBlockNumber * mCurrentSpec.mColumns);                    for (int col = 0; col < mCurrentSpec.mColumns; col++) {                        int spacing = mCurrentSpec.mCellSpacing;                        int leftSpacing = mCurrentSpec.mLeftEdgePadding;                        final int yPos = spacing;                        final int xPos = leftSpacing                                + (col * (mCurrentSpec.mCellWidth + spacing));                        int pos = base + col;                        if (pos >= count)                            break;                        Bitmap b = mGallery.mAllImages.getImageAt(pos);                        if (b == null) {                            return 0;                        }                        drawBlockBitmap(b, xPos, yPos, mCurrentSpec.mCellWidth, mCurrentSpec.mCellHeight);                    }                    return 1;                }                private int loadSelImage(int pos) {                    final int yPos = 0;                    final int xPos = 0;                    Bitmap b = mGallery.mAllImages.getImageAt(pos);                    drawSelBlockBitmap(b, xPos, yPos, sSelBlockWidth,                            sSelBlockHeight);                    return 1;                }                private void drawBlockBitmap(Bitmap b, int left, int top,                        int width, int height) {                    mCanvas.setBitmap(mBitmap);                    if (b != null) {                        //根据图片的大小进行裁剪或缩放,形状均为正方形。                        int w = width;                        int h = height;                        int bw = b.getWidth();                        int bh = b.getHeight();                        int deltaW = bw - w;                        int deltaH = bh - h;                        if (deltaW < 10 && deltaH < 10) {                            int halfDeltaW = deltaW / 2;                            int halfDeltaH = deltaH / 2;                            android.graphics.Rect src = new android.graphics.Rect(                                    0 + halfDeltaW, 0 + halfDeltaH, bw                                            - halfDeltaW, bh - halfDeltaH);                            android.graphics.Rect dst = new android.graphics.Rect(                                    left, top, left + w, top + h);                            mCanvas.drawBitmap(b, src, dst, mPaint);                        } else {                            int l = (bw - w) / 2;                            int t = (bh - h) / 2;                            android.graphics.Rect src = new android.graphics.Rect(                                    l, t, l + w, t + h);                            android.graphics.Rect dst = new android.graphics.Rect(                                    left, top, left + w, top + h);                            mCanvas.drawBitmap(b, src, dst, mPaint);                        }                    } else {                        //如果缩略图不能获得,则使用默认的错误图片代替                        Bitmap error = mImageBlockManager.getErrorBitmap();                        int w = error.getWidth();                        int h = error.getHeight();                        Rect source = new Rect(0, 0, w, h);                        int l = (w - w) / 2 + left;                        int t = (h - h) / 2 + top;                        Rect dest = new Rect(l, t, l + w, t + h);                        mCanvas.drawBitmap(error, source, dest, mPaint);                    }                    int[] stateSet = EMPTY_STATE_SET;                    paintBorder(stateSet, left, top, left + width, top + height);                } 


[解决办法]
recycle并不能及时回收图片,只是告诉虚拟机我需要回收该图片资源,Java中没有手工回收资源的方法。。
1、修改android底层的内存限制。。。放开内存
2、用楼上的做法进行缩放, opts.inSampleSize = 2;表明缩放为原图的长宽各一半。。。用弱引用引用图片,保证及时的回收。。


[解决办法]
执行了bitmap.recycle()后,直接让bitmap对象赋予null,这样可以立即释放的。不过要说的是android处理大图片很愁人的,ram太小了,没办法,vm限制也大,哈哈