I'm a newbie to monodroid and I have two killers here I wish someone can help me to resolve:
I have a monodrid app which uploads an image to a web service, the images comes from the device camera or the Pictures gallery.
First thing is I use the following code to take a picture from the device camera:
var intent = new Intent(MediaStore.ActionImageCapture);
var availableActivities = this.PackageManager.QueryIntentActivities(intent, PackageInfoFlags.MatchDefaultOnly);
if (availableActivities != null && availableActivities.Count > 0)
{
var dir = new Java.IO.File(
Android.OS.Environment.GetExternalStoragePublicDirectory(
Android.OS.Environment.DirectoryPictures), "myapp");
if (!dir.Exists())
{
dir.Mkdirs();
}
_file = new Java.IO.File(dir, String.Format("image-{0}.jpg", Guid.NewGuid()));
StaticDataHolder.ImageUri = Android.Net.Uri.FromFile(_file);
intent.PutExtra(MediaStore.ExtraOutput, Android.Net.Uri.FromFile(_file));
StartActivityForResult(intent, RESULT_CAMERA_CAPTURE);
}
And this code to read scaled Bitmap from StaticDataHolder.ImageUri into an ImageView control so the user can confirm weather to use the selected image or not:
Bitmap largeBitmap = null;
try
{
image.SetImageBitmap(null);
if (Bitmap != null)
{
Bitmap.Recycle();
Bitmap.Dispose();
}
largeBitmap = MediaStore.Images.Media.GetBitmap(ContentResolver, StaticDataHolder.ImageUri);
Bitmap = GetScaledImage(largeBitmap);
SetImageFromBitmap(image, Bitmap);
return true;
}
catch (Java.Lang.OutOfMemoryError)
{
return false;
}
finally
{
if (largeBitmap != null)
{
largeBitmap.Recycle();
largeBitmap.Dispose();
}
}
The second issue is when the user confirm the selected image weather its taken from the camera or picked from the gallery, I create a new Bitmap to be compressed and sent to a web service which I host using the following code:
byte[] buffer = null;
MemoryStream ms = null;
Bitmap bmp = null;
ms = new MemoryStream();
bmp = MediaStore.Images.Media.GetBitmap(ContentResolver, StaticDataHolder.ImageUri);
bmp.Compress(Bitmap.CompressFormat.Jpeg, 60, ms);
buffer = ms.GetBuffer();
ms.Dispose();
bmp.Recycle();
bmp.Dispose();
and then I pass the buffer to the web service method.
This code will work perfectly the first time I start the app, But when I try to load a second image I get OutOfMemoryError exception and the image is not loaded.
How i can load a Bitmap and dispose it probably so I can avoid this exception?. Please note that every step here is managed via separate activities:
1.Take or choose a photo activity. 2.Confirm the selected photo activity. 3.Load the selected photo and send it to the web service activity.
As far as I know the activity is disposed when finished so by default all resources used in it will also be disposed but in my case its appears to be not!.
I have searched it for 3 days with no luck, any help would be much appreciated.
Bitmaps in general are a pain on Android since they live in the native heap and are not directly garbage collected, well in Android < 2.3.x at least. Have you tried using BitmapFactory?
For example:
var opts = new BitmapFactory.Options() { InPurgeable = true, InInputShareable = true };
var bitmap = BitmapFactory.DecodeFile (pathToBitmap, opts);
Will cause the result bitmap to be purgeable from memory when needed (http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With