shayeste
shayeste

Reputation: 35

OutOfMemoryError when creating bitmap after screen rotation

I am using PhotoView for showing Images in my app, but when I rotates device 3 or 4 time I get OutOfMemory error, what is the problem? do I clean the PhotoView correctly?

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        // Get intent, action and MIME type
        Intent intent = getIntent();
        String action = intent.getAction();
        String type = intent.getType();

        if (Intent.ACTION_SEND.equals(action) && type != null) {
            if ("text/plain".equals(type)) {
                handleSendText(intent); // Handle text being sent
            } else if (type.startsWith("image/")) {
                handleSendImage(intent); // Handle single image being sent
            }
        } else if (Intent.ACTION_SEND_MULTIPLE.equals(action) && type != null) {
            if (type.startsWith("image/")) {
                handleSendMultipleImages(intent); // Handle multiple images being sent
            }
        } else {
            // Handle other intents, such as being started from the home screen
        }


    }



    void handleSendText(Intent intent) {
        String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
        if (sharedText != null) {
            Toast.makeText(this, sharedText, Toast.LENGTH_LONG).show();
        }
    }

    void handleSendImage(Intent intent) {
        Uri imageUri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
        if (imageUri != null) {
            Toast.makeText(this, imageUri.toString(), Toast.LENGTH_LONG).show();
            try {
                Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);//OOM here
                PhotoView photoView = (PhotoView) findViewById(R.id.img);
                photoView.setImageBitmap(bitmap);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    void handleSendMultipleImages(Intent intent) {
        ArrayList<Uri> imageUris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
        if (imageUris != null) {
        }



    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        ((PhotoView)findViewById(R.id.img)).setImageBitmap(null);
        ((PhotoView)findViewById(R.id.img)).setImageDrawable(null);
        ((PhotoView)findViewById(R.id.img)).setImageResource(0);
    }
}

Upvotes: 2

Views: 61

Answers (1)

Nabin Bhandari
Nabin Bhandari

Reputation: 16409

Sometimes, just setting the bitmap or drawable of an ImageView to null is not enough. You will need to recycle the bitmap explicitly.

To do so, convert your variable bitmap to a field (global variable) and recycle it on destroy.

public class MainActivity extends AppCompatActivity {

    private Bitmap bitmap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...    

While loading the bitmap, load as below:

if(bitmap != null) bitmap.recycle();
bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);

And finally inside onDestroy, recycle the bitmap as:

@Override
protected void onDestroy() {
    ((PhotoView)findViewById(R.id.img)).setImageBitmap(null);
    if(bitmap != null) bitmap.recycle();
    super.onDestroy();
}

Upvotes: 1

Related Questions