2

Androidを使い始めました。私は向きを変えてアプリを試しました。アンドロイド - OutofMemoryError - ビットマップサイズがVM予算を超えています。向きの変更

ビットマップサイズがVMの予算を超えています。 stackoverflowで多くのポストを通過し、問題を把握できませんでした。例外がsetContentView(R.layout.level1)にスローしています。 inCreateでこれは向きを変えると起こります。

私はすべてのフォーラムとstackoverflowを試しましたが、それを理解できませんでした。これを過去3日間修正しようとしています。

以下は、インテントとstartActivityを使用したボタンクリック時の別のアクティビティから呼び出されているクラスです。

@Override 
public void onCreate(Bundle savedInstanceState) { 
    Log.d("onCreate", "onCreate"); 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.level1); 
    if(!isOrientationChanged) //this part is executed if orientation is not changed (activity starts as usual) 
    { 
     drawableList = new ArrayList<Drawable>(); 
     drawableList.add(getResources().getDrawable(colorEnum[0])); 
     drawableList.add(getResources().getDrawable(colorEnum[1])); 
    } 
    isOrientationChanged = false; 
    timeView = (TextView) findViewById(R.id.timeView); 
    colorButton = (Button) findViewById(R.id.game_button); 
} 


@Override 
protected void onResume() { 
    scoreView = (TextView) findViewById(R.id.scoreView); 
    scoreView.setText("Score: " + score); 
    hand.postDelayed(runThread, 0); 
    super.onResume(); 
} 


@Override  
public Object onRetainNonConfigurationInstance()  {   
isOrientationChanged = true; 
return null; //as you are not returning an object you are not leaking memory here  
} 

@Override 
protected void onPause() { 
    hand.removeCallbacks(runThread); 
    super.onPause(); 
} 

@Override 
    protected void onDestroy() { 
     super.onDestroy(); 
     unbindDrawables(findViewById(R.id.RootView)); 
     System.gc(); 
    } 

    private void unbindDrawables(View view) { 
     if (view.getBackground() != null) { 
      view.getBackground().setCallback(null); 
     } 
     if (view instanceof ViewGroup) { 
      for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) { 
       Log.d("onDestroy","Inside loop to getting child "+((ViewGroup) view).getChildAt(i)); 
       unbindDrawables(((ViewGroup) view).getChildAt(i)); 
      } 
      ((ViewGroup) view).removeAllViews(); 
     } 
     hand.removeCallbacks(runThread); 
    } 

/** The run thread. */ 
Thread runThread = new Thread() { 
    @Override 
    public void run() { 
     timeView.setText("Time Left: " + timeLeftVal); 
       : 
       : 
       : 
     } else { 
     changeColor(); 
     : 
     : 
      hand.postDelayed(runThread, GET_DATA_INTERVAL); 
     } 
    } 
}; 
/** 
* Change color. 
*/ 
private void changeColor() { 
    colorButton.setBackgroundDrawable(drawableList.get(randomNum)); 

}のonCreate方法において

  1. 、描画可能なリストを作成し、最初の負荷でそれを初期化します。
  2. スレッドを使用してボタン画像の背景をランダムに設定する
  3. unbindDrawables()メソッドonDestroyを呼び出すと、向きの変更時に古いビューがメモリから削除されます。
  4. hand.removeCallbacks(runThread)もonPause方法onRetainNonConfigurationInstanceにヌル戻さ
  5. ()私は、問題を修正し

に呼び出されます。 小さな間違いがこの大きな問題となりました。ハンドラでRunnableの代わりにThreadを使用しました。したがって、removeCallbackは期待どおりに機能しませんでした。

+0

行う ?手動で対処するためにオリエンテーションの変更をアクティビティに渡しているのですか、古い方法で行ったり、頻繁に破壊や再構築を行ったりしていますか? – Chris

+0

読み込んでいるイメージのサイズは?何枚の画像をロードしていますか? Chrisが言ったように、オリエンテーションの変更では、すべてのアクティビティが破棄されて再読み込みされます。 問題はおそらく、以前の向きの画像がまだ読み込まれていて、次の向きの画像が読み込まれていることです。 WMはメモリ不足のため、アプリはクレイです。 ** unbindDrawables()** ** System.gc()**は、次のイメージをロードする前にイメージがアンロードされることを保証しません。 – jobesu14

+1

これについての素晴らしい記事:http://android-developers.blogspot.com/2009/02/faster-screen-orientation-change.html – MobileCushion

答えて

関連する問題