52731

android bitmap out-of-memory error after getting same image twice in a row

Question:

I have a program that is supposed to grab an image from a user's gallery and then display the image in a subsequent activity. As part of my testing, I try to do the operation twice in a row: in ViewImageActivity I click on the button that takes me to the gallery; pick an image; then see the image in FriendsActivity. Then I click the back button and repeat the process. The second time around I always get a ava.lang.OutOfMemoryError. I am including the error log:

04-26 09:43:57.911: W/dalvikvm(30841): threadid=1: thread exiting with uncaught exception (group=0x40c231f8) 04-26 09:43:57.918: E/AndroidRuntime(30841): FATAL EXCEPTION: main 04-26 09:43:57.918: E/AndroidRuntime(30841): java.lang.OutOfMemoryError 04-26 09:43:57.918: E/AndroidRuntime(30841): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method) 04-26 09:43:57.918: E/AndroidRuntime(30841): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:493) 04-26 09:43:57.918: E/AndroidRuntime(30841): at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:299) 04-26 09:43:57.918: E/AndroidRuntime(30841): at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:324) 04-26 09:43:57.918: E/AndroidRuntime(30841): at com.example.game.utils.FileUtils.imageFromGallery(FileUtils.java:87) 04-26 09:43:57.918: E/AndroidRuntime(30841): at com.example.game.utils.FileUtils.unmarshallBitmap(FileUtils.java:71) 04-26 09:43:57.918: E/AndroidRuntime(30841): at com.example.game.FriendsActivity.onCreate(FriendsActivity.java:46) 04-26 09:43:57.918: E/AndroidRuntime(30841): at android.app.Activity.performCreate(Activity.java:4638) 04-26 09:43:57.918: E/AndroidRuntime(30841): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1051) 04-26 09:43:57.918: E/AndroidRuntime(30841): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1940) 04-26 09:43:57.918: E/AndroidRuntime(30841): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2001) 04-26 09:43:57.918: E/AndroidRuntime(30841): at android.app.ActivityThread.access$600(ActivityThread.java:129) 04-26 09:43:57.918: E/AndroidRuntime(30841): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1153) 04-26 09:43:57.918: E/AndroidRuntime(30841): at android.os.Handler.dispatchMessage(Handler.java:99) 04-26 09:43:57.918: E/AndroidRuntime(30841): at android.os.Looper.loop(Looper.java:137) 04-26 09:43:57.918: E/AndroidRuntime(30841): at android.app.ActivityThread.main(ActivityThread.java:4516) 04-26 09:43:57.918: E/AndroidRuntime(30841): at java.lang.reflect.Method.invokeNative(Native Method) 04-26 09:43:57.918: E/AndroidRuntime(30841): at java.lang.reflect.Method.invoke(Method.java:511) 04-26 09:43:57.918: E/AndroidRuntime(30841): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791) 04-26 09:43:57.918: E/AndroidRuntime(30841): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:558) 04-26 09:43:57.918: E/AndroidRuntime(30841): at dalvik.system.NativeStart.main(Native Method) 04-26 09:44:00.997: I/Process(30841): Sending signal. PID: 30841 SIG: 9

My program is written like so:

ViewImageActivity dispatch intent to get photo from image gallery; then onActivityResult calls FriendsActivity. FriendsActivity in turn calls FileUtils's static method unmarshallBitmap to get the image for displaying. See following snippets:

ViewImageActivity:

public void dispatchGalleryIntent(View view) { Intent gallery = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(gallery, LOAD_IMAGE_REQUEST_CODE); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK) { if (requestCode == LOAD_IMAGE_REQUEST_CODE) { imageUri = data.getData(); } dispatchIntentToFriendsActivity(); } } private void dispatchIntentTo FriendsActivity() { Intent intent = new Intent(this, FriendsActivity.class); intent.putExtra(IMAGE_URI, imageUri); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); }

FriendsActivity

@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_friends); Uri imageUri = (Uri) getIntent().getExtras().get(IMAGE_URI); myImage = FileUtils.unmarshallBitmap(imageUri, getContentResolver()); ... }

FileUtils

public static Bitmap unmarshallBitmap(Uri imageUri, ContentResolver resolver) { return imageFromGallery(imageUri, resolver); } private static Bitmap imageFromGallery(Uri imageUri, ContentResolver resolver) { try { String[] filePathColumn = { MediaStore.Images.Media.DATA }; Cursor cursor = resolver.query(imageUri, filePathColumn, null, null, null); cursor.moveToFirst(); int columnIndex = cursor.getColumnIndex(filePathColumn[0]); String picturePath = cursor.getString(columnIndex); cursor.close(); return BitmapFactory.decodeFile(picturePath); } catch (Exception x) { return null; } }

BTW: I already saw <a href="https://stackoverflow.com/questions/12016716/how-to-solve-the-out-of-memory-issue-while-displaying-image-in-android?rq=1" rel="nofollow">How to solve the Out of Memory issue while displaying image in android?</a>. My image loads fine the first time. The problem is if user change their mind and decide to choose a different image (back button and repeat), then the app crash as explained above.

Answer1:

Recycle the currently loaded bitmap image when the user presses the back button and goes of a different image

myImage.recycle();

Answer2:

You should prepare the image for display by loading it with options.inJustDecodeBounds = true; and then adjusting the samplesize.

See: <a href="http://developer.android.com/training/displaying-bitmaps/" rel="nofollow">http://developer.android.com/training/displaying-bitmaps/</a>

Apart from that, are you calling bitmap.recycle() when you no longer need the bitmap? The first could still be in memory when you load the second, causing the error.

Recommend

  • Can't create project with Google Map android API V2
  • Simple Cursor Adapter and Listview
  • Take and crop image with Cooliris
  • How to add a maven manifest to an AAR which specifies dependencies
  • Firebase notification integration throws java.lang.IncompatibleClassChangeError
  • Android throw DeadObjectException with LOG: Transaction failed on small parcel; remote process proba
  • Permission Denial: startForeground requires android.permission.FOREGROUND_SERVICE
  • Getting Nullpointer exception when UnitTesting Android TabActivity
  • Fatal Exception: android.view.WindowManager$BadTokenException Unable to add window — token is not va
  • Can't resolve CalledFromWrongThreadException with Handler
  • NullPointerException in setOnClickListener
  • How I can use Realm to parse a large JSON and storing data
  • Got this error while trying to integrate Facebook login for Android-“couldn't find the URL”. Wh
  • Android phone and bluetooth device communication error
  • NoSuchMethodError on ews-java-api
  • Android: Memory error because of an ImageView?
  • Android IntentService triggered with null intent
  • APS Cloud Push - Payload is null
  • Android: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widg
  • MultiDexExtractor in wrong dex file
  • Creating certificate using makecert without pvk file
  • c# Resize parent control when a child pictureBox changes the Image
  • App crashing on clicking on EditText with latest updates (gradle 4.4 - android studio 3.1)
  • Class not found using the boot class loader
  • How to search and isolate attributes of FASTA formatted text in R
  • Android: posting message to HandlerThread makes UI thread unresponsive or gives IllegalStateExceptio
  • Cannot convert a char value to money. The char value has incorrect syntax
  • Unmarshalling unknown type code exception while resuming
  • Javascript Callbacks with Object constructor
  • Can a Chrome extension content script make an jQuery AJAX request for an html file that is itself a
  • Weird JavaScript statement, what does it mean?
  • Apache 2.4 - remove | delete | uninstall
  • Windows forms listbox.selecteditem displaying “System.Data.DataRowView” instead of actual value
  • Unit Testing MVC Web Application in Visual Studio and Problem with QTAgent
  • Benchmarking RAM performance - UWP and C#
  • How can I use `wmic` in a Windows PE script?