Handling large images efficiently (to avoid OutOfMemoryError)
This looks like a bug:


while ((halfHeight / inSampleSize) &gt; dstWidth
        &amp;&amp; (halfWidth / inSampleSize) &gt; dstWidth) {



You probably meant this way:

while ((halfHeight / inSampleSize) &gt; dstHeight
        &amp;&amp; (halfWidth / inSampleSize) &gt; dstWidth) {




In onDestroy you call bitmap1.recycle(). One problem with that is bitmap1 might be null. The bigger problem is that you try to decode 3 bitmaps earlier, and bitmap1 will point to the last one, so you will recycle only the last one, neglecting the first two. 

I'm not sure this is necessary at all, and I cannot find the relevant documentation. If it's really necessary to manually recycle all Bitmaps like this, then you need to store the references of all the Bitmaps you decoded, so that you can recycle on in onDestroy.



This looks a bit like magic, though mostly not your fault:


BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;

BitmapFactory.decodeResource(getResources(), R.drawable.image1);
BitmapFactory.decodeResource(getResources(), R.drawable.image2);
BitmapFactory.decodeResource(getResources(), R.drawable.image3);

int srcWidth = o.outWidth;
int srcHeight = o.outHeight;



If I understand the docs correctly, you set o.inJustDecodeBounds = true so that you can run BitmapFactory.decodeResource(...) without allocating memory for images, so that you can query o.outWidth for image dimensions. If indeed such magic is going on, some comments would be nice.

I suspect that if you call BitmapFactory.decodeResource(...) 3 times, o.outWidth will have the width of only the last image. So you might want to rework this, extracting the main processing to a private method, and running it for each image separately.

Also in the docs, if decoding fails, then o.outWidth will be set to -1, and you might want to add some checks to handle that case gracefully.



This pattern is repeated 3 times:


bitmap1 = BitmapFactory.decodeResource(getResources(), R.drawable.image1, o);
iv1.setImageBitmap(bitmap1);



It would be good to extract this to a private method:

private void setImageBitmap(int viewId, int imageId, BitmapFactory.Options options) {
    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), imageId, options);
    ImageView view = (ImageView) findViewById(viewId);
    view.setImageBitmap(bitmap);
}


Which you can call with:

setImageBitmap(int R.id.iv1, int R.drawable.image1, o);
setImageBitmap(int R.id.iv2, int R.drawable.image2, o);
setImageBitmap(int R.id.iv3, int R.drawable.image3, o);


If indeed you need to recycle the Bitmaps in onDestroy, then the new setImageBitmap helper is a good place to add the decoded Bitmap to a collection.