-4

I have application where I get photo from camera and show it in imageview.

Uri bitmapPictureUri = intent.getParcelableExtra(TaskActivity.PHOTO);
            Bitmap bitmap = null;

            try {

                bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), bitmapPictureUri);
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            int nh = (int) (bitmap.getHeight() * (512.0 / bitmap.getWidth()));
            bitmapPicture = Bitmap.createScaledBitmap(bitmap, 512, nh, true);
            WeakReference<Bitmap> bm = new WeakReference<Bitmap>(bitmap);
            WeakReference<Bitmap> bm2 = new WeakReference<Bitmap>(bitmapPicture);
            picture.setImageBitmap(bm2.get());

Everything works fine untill I change orientation. When I change first time is ok, but when I rotate again I get outofMemory:

07-23 11:43:18.840: E/AndroidRuntime(12024): FATAL EXCEPTION: main
07-23 11:43:18.840: E/AndroidRuntime(12024): java.lang.OutOfMemoryError
07-23 11:43:18.840: E/AndroidRuntime(12024):    at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
07-23 11:43:18.840: E/AndroidRuntime(12024):    at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:529)
07-23 11:43:18.840: E/AndroidRuntime(12024):    at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:601)
07-23 11:43:18.840: E/AndroidRuntime(12024):    at android.provider.MediaStore$Images$Media.getBitmap(MediaStore.java:803)
07-23 11:43:18.840: E/AndroidRuntime(12024):    at PhotoController.onCreate(PhotoController.java:117)
07-23 11:43:18.840: E/AndroidRuntime(12024):    at android.app.Activity.performCreate(Activity.java:5104)
07-23 11:43:18.840: E/AndroidRuntime(12024):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
07-23 11:43:18.840: E/AndroidRuntime(12024):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
07-23 11:43:18.840: E/AndroidRuntime(12024):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
07-23 11:43:18.840: E/AndroidRuntime(12024):    at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3692)
07-23 11:43:18.840: E/AndroidRuntime(12024):    at android.app.ActivityThread.access$700(ActivityThread.java:141)
07-23 11:43:18.840: E/AndroidRuntime(12024):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1240)
07-23 11:43:18.840: E/AndroidRuntime(12024):    at android.os.Handler.dispatchMessage(Handler.java:99)
07-23 11:43:18.840: E/AndroidRuntime(12024):    at android.os.Looper.loop(Looper.java:137)
07-23 11:43:18.840: E/AndroidRuntime(12024):    at android.app.ActivityThread.main(ActivityThread.java:5039)
07-23 11:43:18.840: E/AndroidRuntime(12024):    at java.lang.reflect.Method.invokeNative(Native Method)
07-23 11:43:18.840: E/AndroidRuntime(12024):    at java.lang.reflect.Method.invoke(Method.java:511)
07-23 11:43:18.840: E/AndroidRuntime(12024):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
07-23 11:43:18.840: E/AndroidRuntime(12024):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
07-23 11:43:18.840: E/AndroidRuntime(12024):    at dalvik.system.NativeStart.main(Native Method)

Any ideas how can avoid this problem? I try simpleSize, weakreferences, bitmap.recycle. System.gc() and nothing.

dakshbhatt21
  • 3,558
  • 3
  • 31
  • 40
edi233
  • 3,511
  • 13
  • 56
  • 97

3 Answers3

1

I resolve my problem by:

protected void onDestroy() {
        super.onDestroy();
        bitmapPicture.recycle();
        bitmap.recycle();
        unbindDrawables(findViewById(R.id.picture_measure_picture));
        System.gc();
    }

    private void unbindDrawables(View view) {
        if (view.getBackground() != null) {
        view.getBackground().setCallback(null);
        }
        if (view instanceof ViewGroup) {
            for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
            unbindDrawables(((ViewGroup) view).getChildAt(i));
            }
        ((ViewGroup) view).removeAllViews();
        }
    }
edi233
  • 3,511
  • 13
  • 56
  • 97
0

Here how I am doing it. You have to use decodeUri method I have added below to get bitmap from URI.

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    if (resultCode == RESULT_OK) {
            if(data != null){
                Uri dataUri = data.getData();

                Bitmap bitmap;
                try {
                    bitmap = decodeUri(dataUri);
                    imageView.setImageBitmap(bitmap);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }

                }

    }
}

this method will optimize memory and your Exception will never occur again.

   private Bitmap decodeUri(Uri selectedImage) throws FileNotFoundException {

    // Decode image size
    BitmapFactory.Options o = new BitmapFactory.Options();
    o.inJustDecodeBounds = true;
    BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImage), null, o);

    // The new size we want to scale to
    final int REQUIRED_SIZE = 140;

    // Find the correct scale value. It should be the power of 2.
    int width_tmp = o.outWidth, height_tmp = o.outHeight;
    int scale = 1;
    while (true) {
        if (width_tmp / 2 < REQUIRED_SIZE
           || height_tmp / 2 < REQUIRED_SIZE) {
            break;
        }
        width_tmp /= 2;
        height_tmp /= 2;
        scale *= 2;
    }

    // Decode with inSampleSize
    BitmapFactory.Options o2 = new BitmapFactory.Options();
    o2.inSampleSize = scale;
    return BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImage), null, o2);

}

P.S:- This decodeUri method i read somewhere on SO, is not my code. Cheers!!

AAnkit
  • 27,299
  • 12
  • 60
  • 71
0

use imageloader class.This will resolve bitmap out of memory exception problem.

http://www.androidhive.info/2012/07/android-loading-image-from-url-http/

Vibhor Bhardwaj
  • 3,071
  • 5
  • 28
  • 49