Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Android

[Ribbit] OutOfMemoryError when sending image (FileHelper, ImageResizer)

Anytime that I try to send a picture or video using Ribbit (and I can add/remove friends, take the picture in app, select the picture in app, and select the people I want to send it to with no errors), the app crashes after I press 'send'.

Here's a shortened version of the logcat error I get (the full version is posted at the bottom of this question):

E/AndroidRuntime(4375):     at com.teamtreehouse.ribbit.ImageResizer.resizeImage(ImageResizer.java:28)

E/AndroidRuntime(4375):     at com.teamtreehouse.ribbit.ImageResizer.resizeImageMaintainAspectRatio(ImageResizer.java:57)

E/AndroidRuntime(4375):     at com.teamtreehouse.ribbit.FileHelper.reduceImageForUpload(FileHelper.java:67)

E/AndroidRuntime(4375):     at com.teamtreehouse.ribbit.RecipientsActivity.createMessage(RecipientsActivity.java:174)

E/AndroidRuntime(4375):     at com.teamtreehouse.ribbit.RecipientsActivity.onOptionsItemSelected(RecipientsActivity.java:129)

I picked out those five specific errors because those were the ones related to code I'd actually written or, on other attempts, pasted into my project files, and thus were where I imagine the problem lies without it being something wayyy above my knowledge level. Two in ImageResizer.java, two in RecipientsActivity.java, and one in FileHelper.java.

Here are the lines of code to which those errors refer: RecipientsActivity line 129 within 'case R.id.action_send'

ParseObject message = createMessage();

RecipientsActivity line 174 within 'if (mFileType.equals(ParseConstants.TYPE_IMAGE)) {'

fileBytes = FileHelper.reduceImageForUpload(fileBytes);

FileHelper line 67 within 'public static byte[] reduceImageForUpload(byte[] imageData) {'

Bitmap bitmap = ImageResizer.resizeImageMaintainAspectRatio(imageData, SHORT_SIDE_TARGET);

ImageResizer line 28 within 'public static Bitmap resizeImage(byte[] imageData, int targetWidth, int targetHeight) {'

Bitmap reducedBitmap = BitmapFactory.decodeByteArray(imageData, 0, imageData.length, options);

ImageResizer line 57 within 'public static Bitmap resizeImageMaintainAspectRatio(byte[] imageData, int shorterSideTarget) {'

return resizeImage(imageData, targetWidth, targetHeight);

Okay, so that's a decent amount of code. Helpfully, even for a novice like myself, I think it might tell a plausible story as to what my problem is:

A. RecipientsActivity checks, "Is file an image? It is? Okay, it's probably going to be too big. Let's size it down. Go talk to FileHelper."

B. FileHelper is like, "Ok, let's turn this into a bitmap." Maybe this part fails? Then FileHelper says, "And when that's done, let's turn this bitmap back into a smaller image!" and the program is like, "Oh, talk to ImageResizer."

C. ImageResizer tries to take the bitmap and turn it back into a smaller image, but fails; or possibly has no bitmap to even work on in the first place.

D. ImageResizer then tries to say, "Okay, whatever image we got left after all that, let's send it back to RecipientsActivity." The image is, unfortunately, the same image from step A.

E. RecipientsActivity goes "Okay, bitmapping and resizing is done, let's action_send this image, go go go!!!" and tries to send out the still too large image, which promptly eats all my memory and crashes the program.

Whether or not that's what's actually happening, what I do know is that I have no clue as to how to fix the errors in those FileHelper and ImageResizer java classes. What's the error(s) in my code here?

I've tried going through the Ribbit project myself twice. I've tried using Ben's clean project files at different stages in the project. I've tried both Eclipse and Android Studio. And I get this same error at this same stage in the process each time.

Is it a Linux conflict (my OS)? Is it a hardware issue (my phone is a Motorola Atrix 2, which should have more than enough juice under the hood to handle this)? A space problem (3.5 gigs free on the phone, 1.3 on the sd card)? Is the allocation of ~30mb of memory to this app too small (I thought I read that was about standard, maybe even larger than normal)?

I've seen some people with previous issues like this were possibly able to solve them by reducing the SHORT_SIDE_TARGET in FileHelper from '1280' to a smaller number but that didn't do anything for me. i I'm stumped.

This frustrated student would appreciate any further insight into this issue, even if your ultimate conclusion is, "Huh. I'm not sure either."

Let me know if you need to see any additional code.

(full logcat report)

E/Tokenizer(4375): Error opening file '/data/usr/keychars/Generic.kcm', Permission denied.
E/KeyCharacterMap(4375): Error -13 opening key character map file /data/usr/keychars/Generic.kcm.
E/dalvikvm-heap(4375): Out of memory on a 31961104-byte allocation.
E/AndroidRuntime(4375): FATAL EXCEPTION: main
E/AndroidRuntime(4375): java.lang.OutOfMemoryError
E/AndroidRuntime(4375):     at android.graphics.BitmapFactory.nativeDecodeByteArray(Native Method)
E/AndroidRuntime(4375):     at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:441)
E/AndroidRuntime(4375):     at com.teamtreehouse.ribbit.ImageResizer.resizeImage(ImageResizer.java:28)
E/AndroidRuntime(4375):     at com.teamtreehouse.ribbit.ImageResizer.resizeImageMaintainAspectRatio(ImageResizer.java:57)
E/AndroidRuntime(4375):     at com.teamtreehouse.ribbit.FileHelper.reduceImageForUpload(FileHelper.java:67)
E/AndroidRuntime(4375):     at com.teamtreehouse.ribbit.RecipientsActivity.createMessage(RecipientsActivity.java:174)
E/AndroidRuntime(4375):     at com.teamtreehouse.ribbit.RecipientsActivity.onOptionsItemSelected(RecipientsActivity.java:129)
E/AndroidRuntime(4375):     at android.app.Activity.onMenuItemSelected(Activity.java:2552)
E/AndroidRuntime(4375):     at com.android.internal.policy.impl.PhoneWindow.onMenuItemSelected(PhoneWindow.java:969)
E/AndroidRuntime(4375):     at com.android.internal.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:735)
E/AndroidRuntime(4375):     at com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:149)
E/AndroidRuntime(4375):     at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:874)
E/AndroidRuntime(4375):     at com.android.internal.view.menu.ListMenuPresenter.onItemClick(ListMenuPresenter.java:163)
E/AndroidRuntime(4375):     at android.widget.AdapterView.performItemClick(AdapterView.java:292)
E/AndroidRuntime(4375):     at android.widget.AbsListView.performItemClick(AbsListView.java:1082)
E/AndroidRuntime(4375):     at android.widget.AbsListView$PerformClick.run(AbsListView.java:2635)
E/AndroidRuntime(4375):     at android.widget.AbsListView$1.run(AbsListView.java:3306)
E/AndroidRuntime(4375):     at android.os.Handler.handleCallback(Handler.java:605)
E/AndroidRuntime(4375):     at android.os.Handler.dispatchMessage(Handler.java:92)
E/AndroidRuntime(4375):     at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(4375):     at android.app.ActivityThread.main(ActivityThread.java:4722)
E/AndroidRuntime(4375):     at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(4375):     at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(4375):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:787)
E/AndroidRuntime(4375):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:554)
E/AndroidRuntime(4375):     at dalvik.system.NativeStart.main(Native Method)