While testing our app on the Kindle Fire Emulator I needed to verify my image processing was working correctly. By default the emulator has no images in the gallery.
Using Eclipse in the DDMS perspective click on emulator-544 in the Devices tab. In the File Explorer tab find the mnt directory and expand it. Find sdcard under than and then Pictures. You can use the "Push a file onto the device" button to copy image files into that directory.
You can also put them in the mnt\sdcard\DCIM directory or the mnt\sdcard\DCIM\Camera directory. The final directory might not exist but you can create it in the File Explorer.
At this point you will need to stop and restart the emulator. It does not appear to rerun the sdcard scanner while running looking for new files.
Make sure when you create the emulator that you enable "Keyboard support" in the hardware section of the AVD or you will have to click on individual letters to type anything which gets boring rather quickly. You can disable this is you need to test with the soft pop-up keyboard.
Showing posts with label images. Show all posts
Showing posts with label images. Show all posts
Tuesday, October 2, 2012
Thursday, December 1, 2011
Android Out of Memory issues
The dreaded "Out of Memory error" with corresponding "Force Close" on your Android device is very frustrating. It was happening to our users from time to time but today I think I may have found the issue. I won't know for sure if this is a true fix until it is out in the field.
I have a couple of ways to acquire images in our app - you can take a picture with the camera or grab an existing image from the gallery. In either case I have to check out the image size and shrink it down to less than 1 meg of data via scaling, quality compression or both. It has to be less than 1 meg as I am holding the images in a SQLite blob to be sent to the server at a later time. I can't leave things in the gallery due to HIPAA rules and I can't trust the user to not delete the original image between pick it and transmit it time frames.
You can also view the image at any time within my app using a viewer I wrote that allows pinch zoom, drag scrolling, rotation and fit to window functionality. This is where things started to go awry.
If I opened and existing image, exited that activity then tried to capture an image from the camera there was a good chance I would get the out of memory issue. If I just took pictures but never viewed them or waited some amount of time before viewing them it might work just fine. This also depended on the device and version of the OS I was using. To find the issue I opened an image in the viewer then closed the viewer and did a heap dump via DDMS in Eclipse, converted that dump via hprof-conv in the android sdk\tools directory and loaded it up in MAT (memory analysis tool) under Eclipse. The Dominator Tree showed the ImageView of the closed activity to still be holding on to a weak referenced large bitmap. I guess the reference is not weak enough for the GC to kick it out of memory during the camera processing even though I was calling System.gc() before I started the camera bitmap manipulation.
To solve the issue I added the following to the image viewing activity:
/**
* On the way out dump our images
*/
@Override
protected void onDestroy() {
imageView.setOnTouchListener(null);
imageView.setImageBitmap(null);
System.gc();
super.onDestroy();
}
Now after hitting the back button from the image activity I don't have a large weak reference to an image floating about in the heap. I have been able to view, take pictures, view, lather, rinse, repeat without any issues. I was running these test on a ASUS Transformer tablet running OS 3.2.1
I am also making sure I call recycle on the bitmaps I use during my scale / quality reduction routines during the post camera processing.
Probably a good idea to manually release any large images you use in your application as activities go away to avoid these problems. Right now I am not releasing all the smaller images I am using but it might be a good idea to make a sweep through the heap dump to see what else is sneaking around.
Not sure if the System.gc() call is even necessary and I know they recommend you don't call it but at this point I can't see it hurting anything and I am only doing it on activity destroy so I am leaving it in there for good luck and hoping I don't hear of any more OOM crashes in the field.
I have a couple of ways to acquire images in our app - you can take a picture with the camera or grab an existing image from the gallery. In either case I have to check out the image size and shrink it down to less than 1 meg of data via scaling, quality compression or both. It has to be less than 1 meg as I am holding the images in a SQLite blob to be sent to the server at a later time. I can't leave things in the gallery due to HIPAA rules and I can't trust the user to not delete the original image between pick it and transmit it time frames.
You can also view the image at any time within my app using a viewer I wrote that allows pinch zoom, drag scrolling, rotation and fit to window functionality. This is where things started to go awry.
If I opened and existing image, exited that activity then tried to capture an image from the camera there was a good chance I would get the out of memory issue. If I just took pictures but never viewed them or waited some amount of time before viewing them it might work just fine. This also depended on the device and version of the OS I was using. To find the issue I opened an image in the viewer then closed the viewer and did a heap dump via DDMS in Eclipse, converted that dump via hprof-conv in the android sdk\tools directory and loaded it up in MAT (memory analysis tool) under Eclipse. The Dominator Tree showed the ImageView of the closed activity to still be holding on to a weak referenced large bitmap. I guess the reference is not weak enough for the GC to kick it out of memory during the camera processing even though I was calling System.gc() before I started the camera bitmap manipulation.
To solve the issue I added the following to the image viewing activity:
/**
* On the way out dump our images
*/
@Override
protected void onDestroy() {
imageView.setOnTouchListener(null);
imageView.setImageBitmap(null);
System.gc();
super.onDestroy();
}
Now after hitting the back button from the image activity I don't have a large weak reference to an image floating about in the heap. I have been able to view, take pictures, view, lather, rinse, repeat without any issues. I was running these test on a ASUS Transformer tablet running OS 3.2.1
I am also making sure I call recycle on the bitmaps I use during my scale / quality reduction routines during the post camera processing.
Probably a good idea to manually release any large images you use in your application as activities go away to avoid these problems. Right now I am not releasing all the smaller images I am using but it might be a good idea to make a sweep through the heap dump to see what else is sneaking around.
Not sure if the System.gc() call is even necessary and I know they recommend you don't call it but at this point I can't see it hurting anything and I am only doing it on activity destroy so I am leaving it in there for good luck and hoping I don't hear of any more OOM crashes in the field.
Subscribe to:
Posts (Atom)