3

これが状況です。3つの異なるレイアウトのViewAnimatorがあります。レイアウトごとに異なる背景画像があります。xhdpiデバイスの場合、画像のサイズは1280x800ピクセルで、サイズは約150KBです。ここで問題が発生します。サイズが1280x800、密度が320dpでエミュレータを起動すると、常に次の例外が発生します。

09-02 08:22:46.408: D/dalvikvm(1291): GC_EXTERNAL_ALLOC freed 428K, 51% free 2874K/5831K, external 18484K/20407K, paused 83ms
09-02 08:22:46.419: E/dalvikvm-heap(1291): 1366400-byte external allocation too large for this process.
09-02 08:22:46.498: I/dalvikvm-heap(1291): Clamp target GC heap from 25.089MB to 24.000MB
09-02 08:22:46.498: E/GraphicsJNI(1291): VM won't let us allocate 1366400 bytes
09-02 08:22:49.208: E/AndroidRuntime(1291): java.lang.OutOfMemoryError: bitmap size exceeds VM budget

誰かが私の問題の解決策または回避策を持っていますか?BitmapFactoryについて何か読んだ。それは役に立ちますか?よろしくお願いします!

編集:これが私のコードです:レイアウトファイルmain_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical" >

<ViewAnimator
    android:id="@+id/viewAnimator"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

   <LinearLayout
        android:id="@+id/LayoutMain"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="vertical"
        android:background="@drawable/background"
        ...some Buttons etc. ...
   </LinearLayout>

   <LinearLayout
        android:id="@+id/layoutGameMenu"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="vertical"
        android:background="@drawable/gameMenu"
        ...some Buttons etc. ...
   </LinearLayout>

   <LinearLayout
        android:id="@+id/layoutHighscores"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:background="@drawable/highscores"
        ...some ListViews etc. ...
   </LinearLayout>

</ViewAnimator>
</LinearLayout>

そしてMainActivity:

private ViewAnimator va;   

@Override
public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.main_layout);
     va = (ViewAnimator) findViewById(R.id.viewAnimator);
     ....
}

....
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if(event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
        if (va.getCurrentView() == findViewById(R.id.layoutHighscores)) {
            va.setInAnimation(inFromRight);
            va.setOutAnimation(outToLeft);
            va.setDisplayedChild(0);
            return true;
        }
        if (va.getCurrentView() == findViewById(R.id.layoutGameMenu)) {
            va.setInAnimation(inFromLeft);
            va.setOutAnimation(outToRight);
            va.setDisplayedChild(0);
            return true;
        }
    } 
    return super.onKeyDown(keyCode, event);
}

これにより、メインメニュー、ハイスコア、ボタン付きのゲームメニューを切り替えて、ゲームモードを開始できます。「クールな」ビューアニメーションが必要なため、これを選択します。

BitmapFactoryメソッドで解決しようとしましたが、変更はありません。

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) {

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);
}

public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;

if (height > reqHeight || width > reqWidth) {
    if (width > height) {
        inSampleSize = Math.round((float)height / (float)reqHeight);
    } else {
        inSampleSize = Math.round((float)width / (float)reqWidth);
    }
}
return inSampleSize;
}
4

1 に答える 1

0

メインの Android サイトのAndroid トレーニングセクションに、この状況をカバーするレッスンがあります。レッスン、Displaying Bitmaps Efficientlyは 4 つのセクションに分かれており、実際の例が含まれており、API レベル 7 以上をサポートしています (これは問題ではないと思います)。

それでも解決しない場合は、コードを投稿して、より具体的なヘルプを提供できるようにすることをお勧めします。;-)

于 2012-09-02T13:57:38.067 に答える