Android outofmemory位图

时间:2015-05-25 23:55:57

标签: android

我使用了以下动画类,因为我有多个图像来制作动画。在第7个动画之后我得到OutofMemoryError。 androidgraphics.Bitmap.createBitmap

public class AnimationsContainer {
public int FPS = 30;  // animation FPS

// single instance procedures
private static AnimationsContainer mInstance;

private AnimationsContainer() {
};

public static AnimationsContainer getInstance() {
    if (mInstance == null)
        mInstance = new AnimationsContainer();
    return mInstance;
}

// animation progress dialog frames
private int[] mProgressAnimFrames = {};

// animation splash screen frames


/**
 * @param imageView 
 * @return progress dialog animation
 */
public FramesSequenceAnimation createProgressDialogAnim(ImageView imageView) {
    return new FramesSequenceAnimation(imageView, mProgressAnimFrames);
}

/**
 * @param imageView
 * @return splash screen animation
 */
public FramesSequenceAnimation createSplashAnim(ImageView imageView, int[] n) {
    return new FramesSequenceAnimation(imageView, n);
}

/**
 * AnimationPlayer. Plays animation frames sequence in loop
 */
public class FramesSequenceAnimation {
private int[] mFrames; // animation frames
private int mIndex; // current frame
private boolean mShouldRun; // true if the animation should continue running. Used to stop the animation
private boolean mIsRunning; // true if the animation currently running. prevents starting the animation twice
private SoftReference<ImageView> mSoftReferenceImageView; // Used to prevent holding ImageView when it should be dead.
private Handler mHandler;
private int mDelayMillis;
private OnAnimationStoppedListener mOnAnimationStoppedListener;

private Bitmap mBitmap = null;
private BitmapFactory.Options mBitmapOptions;

public FramesSequenceAnimation(ImageView imageView, int[] frames) {
    mHandler = new Handler();
    mFrames = frames;
    mIndex = -1;
    mSoftReferenceImageView = new SoftReference<ImageView>(imageView);
    mShouldRun = false;
    mIsRunning = false;
    mDelayMillis = 50;

    imageView.setImageResource(mFrames[0]);

    // use in place bitmap to save GC work (when animation images are the same size & type)
    if (Build.VERSION.SDK_INT >= 11) {
        Bitmap bmp = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
        int width = bmp.getWidth();
        int height = bmp.getHeight();
        Bitmap.Config config = bmp.getConfig();
        mBitmap = Bitmap.createBitmap(width, height, config);
        mBitmapOptions = new BitmapFactory.Options();
        // setup bitmap reuse options. 
        mBitmapOptions.inBitmap = mBitmap;
        mBitmapOptions.inMutable = true;
        mBitmapOptions.inSampleSize = 1;
    }
}

private int getNext() {
    mIndex++;
    if (mIndex == mFrames.length){
        mIndex = mIndex - 1;
    mShouldRun = false;
    }
    return mFrames[mIndex];
}

/**
 * Starts the animation
 */
public synchronized void start() {
    mShouldRun = true;
    if (mIsRunning)
        return;

    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            ImageView imageView = mSoftReferenceImageView.get();
            if (!mShouldRun || imageView == null) {
                mIsRunning = false;
                if (mOnAnimationStoppedListener != null) {
                    mOnAnimationStoppedListener.onAnimationStopped();
                }
                return;
            }

            mIsRunning = true;
            mHandler.postDelayed(this, mDelayMillis);

            if (imageView.isShown()) {
                int imageRes = getNext();
                if (mBitmap != null) { // so Build.VERSION.SDK_INT >= 11
                    Bitmap bitmap = null;
                    try {
                        bitmap = BitmapFactory.decodeResource(imageView.getResources(), imageRes, mBitmapOptions);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    if (bitmap != null) {
                        imageView.setImageBitmap(bitmap);
                    } else {
                        imageView.setImageResource(imageRes);
                        mBitmap.recycle();
                        mBitmap = null;
                    }
                } else {
                    imageView.setImageResource(imageRes);
                }
            }

        }
    };

    mHandler.post(runnable);
}

    /**
     * Stops the animation
     */
    public synchronized void stop() {
        mShouldRun = false;
    }
}
}

任何人都可以解释我为什么并告诉我如何解决它?我已经添加了

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

到我的清单文件。

1 个答案:

答案 0 :(得分:0)

确保您不会保留对不需要的图像的引用可能会有所帮助。这种情况正在发生,因为你可能有#34;标准&#34;内存堆32MB或类似的东西(可能是64MB或16MB)。如果您认为大多数图像都是5MB或更多,那么您的内存不足就不足为奇了。

您可以使用android:largeHeap="true"增加堆大小,如下所示:

How to increase heap size of an android application?

相关问题