Shawnzey
Shawnzey

Reputation: 196

android how to recycle image before loading a new one

I have a out of memory problem here in which i have full screen images being displayed. I want to show images in full screen and I have two buttons to cycle through them to the left or to the right. How can i have the past images be recycled before showing the next to prevent the out of memory exception? or is there an even better way to do so?

here is my class in which i view the image.

public class ImageViewActivity extends Activity
{
private Button btnHome;
private Button btnBack;
private ImageButton btnLeft;
private ImageButton btnRight;
ImageView imageView;
RelativeLayout layout;

int height;
int width;

Bitmap bitmap;
String[] imagesPath;
int position;

// These matrices will be used to move and zoom image
Matrix matrix = new Matrix();
Matrix savedMatrix = new Matrix();

// We can be in one of these 3 states
static final int NONE = 0;
static final int DRAG = 1;
static final int ZOOM = 2;
int mode = NONE;

// Remember some things for zooming
PointF start = new PointF();
PointF mid = new PointF();
float oldDist = 1f;
String savedItemClicked;

@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.imageview_activity);

    btnHome = (Button) findViewById(R.id.btnHome);
    btnBack = (Button) findViewById(R.id.btnBack);
    btnLeft = (ImageButton) findViewById(R.id.leftArrow);
    btnRight = (ImageButton) findViewById(R.id.rightArrow);

    DisplayMetrics displayMetrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
    height = displayMetrics.heightPixels;
    width = displayMetrics.widthPixels;

    imagesPath = getIntent().getStringExtra("IMAGES").split("\\|");
    position = getIntent().getIntExtra("POSITION", 0);

    bitmap = BitmapFactory.decodeFile(imagesPath[position]);

    imageView = (ImageView)findViewById(R.id.displayImage);
    imageView.setImageBitmap(Bitmap.createScaledBitmap(bitmap, width, height, false));

    btnLeft.setOnClickListener(new View.OnClickListener()
    {
        public void onClick(View arg0)
        {
            if (position == 0)
                position = 5;
            else
                position--;

            RectF imageRectF = new RectF(0, 0, width, height);
            RectF viewRectF = new RectF(0, 0, width, height);
            matrix.setRectToRect(imageRectF, viewRectF, Matrix.ScaleToFit.CENTER);

            bitmap = BitmapFactory.decodeFile(imagesPath[position]);
            ImageView imageView = (ImageView)findViewById(R.id.displayImage);
            imageView.setImageBitmap(Bitmap.createScaledBitmap(bitmap, width, height, false));

            imageView.setImageMatrix(matrix);
        }
    });

    btnRight.setOnClickListener(new View.OnClickListener()
    {
        public void onClick(View arg0)
        {
            if (position == 5)
                position = 0;
            else
                position++;

            RectF imageRectF = new RectF(0, 0, width, height);
            RectF viewRectF = new RectF(0, 0, width, height);
            matrix.setRectToRect(imageRectF, viewRectF, Matrix.ScaleToFit.CENTER);

            bitmap = BitmapFactory.decodeFile(imagesPath[position]);
            ImageView imageView = (ImageView)findViewById(R.id.displayImage);
            imageView.setImageBitmap(Bitmap.createScaledBitmap(bitmap, width, height, false));

            imageView.setImageMatrix(matrix);
        }
    });

    btnHome.setOnClickListener(new View.OnClickListener()
    {
        public void onClick(View arg0)
        {
            Intent ActivitySwitch = new Intent(getApplicationContext(), MainMenuActivity.class);
            startActivity(ActivitySwitch);
        }
    });

    btnBack.setOnClickListener(new View.OnClickListener()
    {
        public void onClick(View arg0)
        {
            Intent ActivitySwitch = new Intent(getApplicationContext(), AddClientActivity.class);
            startActivity(ActivitySwitch);
        }
    });

    imageView.setOnTouchListener(new View.OnTouchListener()
    {
        @Override
        public boolean onTouch(View v, MotionEvent event)
        {
            ImageView view = (ImageView) v;
            dumpEvent(event);

            // Handle touch events here...
            switch (event.getAction() & MotionEvent.ACTION_MASK) {
                case MotionEvent.ACTION_DOWN:
                    savedMatrix.set(matrix);
                    start.set(event.getX(), event.getY());
                    mode = DRAG;
                    break;
                case MotionEvent.ACTION_POINTER_DOWN:
                    oldDist = spacing(event);
                    if (oldDist > 10f) {
                        savedMatrix.set(matrix);
                        midPoint(mid, event);
                        mode = ZOOM;
                    }
                    break;
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_POINTER_UP:
                    mode = NONE;
                    break;
                case MotionEvent.ACTION_MOVE:
                    if (mode == DRAG) {
                        // ...
                        matrix.set(savedMatrix);
                        matrix.postTranslate(event.getX() - start.x, event.getY()
                                - start.y);
                    } else if (mode == ZOOM) {
                        float newDist = spacing(event);
                        if (newDist > 10f) {
                            matrix.set(savedMatrix);
                            float scale = newDist / oldDist;
                            matrix.postScale(scale, scale, mid.x, mid.y);
                        }
                    }
                    break;
            }

            view.setImageMatrix(matrix);
            return true;
        }
    });

}

private void dumpEvent(MotionEvent event) {
    String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE",
            "POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" };
    StringBuilder sb = new StringBuilder();
    int action = event.getAction();
    int actionCode = action & MotionEvent.ACTION_MASK;
    sb.append("event ACTION_").append(names[actionCode]);
    if (actionCode == MotionEvent.ACTION_POINTER_DOWN
            || actionCode == MotionEvent.ACTION_POINTER_UP) {
        sb.append("(pid ").append(
                action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
        sb.append(")");
    }
    sb.append("[");
    for (int i = 0; i < event.getPointerCount(); i++) {
        sb.append("#").append(i);
        sb.append("(pid ").append(event.getPointerId(i));
        sb.append(")=").append((int) event.getX(i));
        sb.append(",").append((int) event.getY(i));
        if (i + 1 < event.getPointerCount())
            sb.append(";");
    }
    sb.append("]");
}

/** Determine the space between the first two fingers */
private float spacing(MotionEvent event) {
    float x = event.getX(0) - event.getX(1);
    float y = event.getY(0) - event.getY(1);
    return (float)Math.sqrt(x * x + y * y);
}

/** Calculate the mid point of the first two fingers */
private void midPoint(PointF point, MotionEvent event) {
    float x = event.getX(0) + event.getX(1);
    float y = event.getY(0) + event.getY(1);
    point.set(x / 2, y / 2);
}

thank you for any input and if you need any additional information please feel free to ask!

Upvotes: 0

Views: 71

Answers (2)

Shawnzey
Shawnzey

Reputation: 196

it was a lot simpler then i first imagined. i simply added this

bitmap.recycle();

before i declared my bitmap to the new image.

Upvotes: 1

gabriel carrillo
gabriel carrillo

Reputation: 41

I would either scale down the image or consider using the Picasso image loading library: http://square.github.io/picasso/

It is also really simply to use and prevents a lot Out of Memory Exceptions.

Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);

Upvotes: 1

Related Questions