3

我是 monodroid 的新手,我在这里有两个杀手我希望有人能帮我解决:

我有一个单一的应用程序,它将图像上传到网络服务,图像来自设备相机或图片库。

首先是我使用以下代码从设备相机拍照:

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);
}

这段代码从 StaticDataHolder.ImageUri 读取缩放位图到 ImageView 控件中,以便用户可以确认天气是否使用所选图像:

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();
    }
}

第二个问题是当用户确认选择的图像是从相机拍摄或从画廊中挑选出来的,我创建一个新的位图进行压缩并发送到我使用以下代码托管的 Web 服务:

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();

然后我将缓冲区传递给 Web 服务方法。

此代码将在我第一次启动应用程序时完美运行,但是当我尝试加载第二张图像时,我得到 OutOfMemoryError 异常并且图像未加载。

我如何加载位图并将其处理掉,以便避免此异常?请注意,这里的每一步都通过单独的活动进行管理:

1.拍摄或选择照片活动。2.确认选择的照片活动。3.加载所选照片并将其发送到网络服务活动。

据我所知,该活动在完成后被处置,因此默认情况下,其中使用的所有资源也将被处置,但在我的情况下,它似乎不是!

我已经搜索了 3 天没有运气,任何帮助将不胜感激。

4

1 回答 1

2

一般来说,位图在 Android 上是一个痛苦,因为它们存在于本机堆中并且不直接被垃圾收集,至少在 Android < 2.3.x 中是这样。您是否尝试过使用 BitmapFactory?

例如:

var opts = new BitmapFactory.Options() { InPurgeable = true, InInputShareable = true };
var bitmap = BitmapFactory.DecodeFile (pathToBitmap, opts);

将导致结果位图在需要时从内存中清除(http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html)

于 2012-12-15T01:45:46.567 回答