0

TouchImageView(https://github.com/MikeOrtiz/TouchImageView) を使用してズーム可能な画像を表示するフラグメントを作成しようとしています

フラグメントには、画像を変更するためのスピナーもあります。問題は、最初の画像が正常に読み込まれることですが、スクローラーを使用して画像を変更すると、OutOfMemoryError が発生し、プログラムがクラッシュします。これが私のコードです

public class mapFragment extends SherlockFragment {


String[] Levels = { "Ground Floor", "First Floor",
        "Second Floor", "Third Floor"
};

Button button;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup group, Bundle saved)
{
    View v = inflater.inflate(R.layout.maps_layout, group, false);


    final TouchImageView img = (TouchImageView) v.findViewById(R.id.touchimage1);
    final Bitmap snoop = BitmapFactory.decodeResource(getResources(), R.drawable.groundfloor);
    img.setImageBitmap(snoop);




    final Spinner s = (Spinner) v.findViewById(
            R.id.spinnerlevels);

    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this
            .getActivity().getBaseContext(),
            android.R.layout.simple_spinner_item, Levels);
    s.setAdapter(adapter);

    s.setOnItemSelectedListener(new OnItemSelectedListener() {

        public void onItemSelected(AdapterView<?> parent, View view, 
                int pos, long id) {
            // An item was selected. You can retrieve the selected item using
            // parent.getItemAtPosition(pos)
            int item = s.getSelectedItemPosition();



            if(item ==0){
                snoop.recycle();
                Bitmap snoop = BitmapFactory.decodeResource(getResources(), R.drawable.groundfloor);
                img.setImageBitmap(snoop);
            }
            if(item ==1){
                snoop.recycle();
                Bitmap snoop = BitmapFactory.decodeResource(getResources(), R.drawable.firstfloor);
                img.setImageBitmap(snoop);
            }
            if(item ==2){
                snoop.recycle();
                Bitmap snoop = BitmapFactory.decodeResource(getResources(), R.drawable.secondfloor);
                img.setImageBitmap(snoop);
            }
            if(item ==3){
                snoop.recycle();
                Bitmap snoop = BitmapFactory.decodeResource(getResources(), R.drawable.thirdfloor);
                img.setImageBitmap(snoop);
            }


        }

        public void onNothingSelected(AdapterView<?> parent) {
            // Another interface callback
        }
    });



    img.setMaxZoom(8f);

    return (v);


}

}

「recylce()」は最初の画像を削除して、メモリ内の新しい画像に場所を与えるべきではありませんか? MB 単位の画像サイズは 1.4、1.5、1.5、1.3 です。

4

2 に答える 2

1

「recylce()」は最初の画像を削除して、メモリ内の新しい画像に場所を与えるべきではありませんか?

いいえ、recycle() メソッドは単にこのビットマップを「無効」とマークするだけで、後でガベージ コレクションを実行できます。recycle()メソッドのドキュメントは次のとおりです。

このビットマップに関連付けられたネイティブ オブジェクトを解放し、ピクセル データへの参照をクリアします。これにより、ピクセル データが同期的に解放されることはありません。他に参照がない場合は、ガベージコレクションを許可するだけです。ビットマップは「dead」とマークされます。つまり、getPixels() または setPixels() が呼び出されると例外がスローされ、何も描画されません。この操作は元に戻すことができないため、ビットマップをこれ以上使用しないことが確実な場合にのみ呼び出す必要があります。これは高度な呼び出しであり、このビットマップへの参照がなくなると通常の GC プロセスがこのメモリを解放するため、通常は呼び出す必要はありません。

于 2012-08-31T11:31:26.457 に答える
0

画像の各ピクセルに対して、ヒープは 8 バイトを使用します。では、1754 x 2481 x 8 はどのくらいのメモリですか? 答えは 32.94 MB のヒープ メモリです。多くのデバイスでは、他のものにも使用される 16 MB を超えるヒープはありません。あなたは今あなたの問題を理解していますか?

画像を小さくする必要があります。そうしないと、アプリが飛ぶことはありません:)

于 2012-08-31T11:54:43.077 に答える