3

私はモノドロイドの初心者で、ここに2つのキラーがあります。誰かが私を解決するのを手伝ってくれることを願っています:

画像を Web サービスにアップロードする monodrid アプリがあります。画像はデバイスのカメラまたは写真ギャラリーから取得されます。

まず、次のコードを使用して、デバイスのカメラから写真を撮ります。

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

2 番目の問題は、選択した画像がカメラから取得されたものか、ギャラリーから選択されたものかをユーザーが確認したときに、新しいビットマップを作成して圧縮し、次のコードを使用してホストする 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 サービス メソッドに渡します。

このコードは、アプリを初めて起動したときに完全に機能しますが、2 番目の画像を読み込もうとすると、OutOfMemoryError 例外が発生し、画像が読み込まれません。

この例外を回避できるように、ビットマップをロードして破棄するにはどうすればよいですか? ここでのすべてのステップは、個別のアクティビティによって管理されることに注意してください。

1.写真を撮る、または選ぶ。2.選択したフォトアクティビティを確認します。3.選択した写真を読み込み、Web サービス アクティビティに送信します。

私の知る限り、アクティビティは終了時に破棄されるため、デフォルトではアクティビティで使用されるすべてのリソースも破棄されますが、私の場合はそうではないようです!.

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 に答える