2

我剛開始使用Android。我嘗試了一個方向改變的應用程序。android - OutofMemoryError - 位圖大小超過虛擬機預算 - 在方向更改上

我面臨的位圖大小超過虛擬機預算。已經在stackoverflow中經歷了很多帖子,無法找出問題所在。異常是拋出setContentView(R.layout.level1);在onCreate。當我改變方向時發生這種情況。

我試過所有論壇和計算器,但無法弄清楚。試圖在過去3天內解決這個問題。

下面的類正在使用intent和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)); 

}

  1. 在onCreate方法,創造了繪製列表,並對其進行初始化上的第一負載。
  2. 使用線程隨機設置按鈕圖像背景
  3. 調用unbindDrawables()方法onDestroy,以便在方向上更改舊視圖將從內存中刪除。
  4. hand.removeCallbacks(runThread)也被稱爲的onPause方法在onRetainNonConfigurationInstance返回null
  5. ()

我已經解決了這一問題。 小錯誤導致了這個大問題。我在處理程序中使用了Thread而不是Runnable。因此,removeCallback沒有按預期工作。

+0

什麼是你的清單文件安裝到做什麼? ,您是否將方向更改傳遞給活動以進行手動處理,或者您要進行舊式並經常崩潰的摧毀和重建? – Chris

+0

你正在加載的圖像的大小是多少?你加載了多少圖片?正如克里斯所說,在方向轉變時,所有的活動都被剝離並重新加載。 問題可能是先前方向的圖像仍然被加載,而下一個方向的圖像正在加載。應用程序crah,因爲WM內存不足。 調用** unbindDrawables()** ** System.gc()**不確保在加載下一張圖像之前卸載圖像。 – jobesu14

+1

關於此的好文章:http://android-developers.blogspot.com/2009/02/faster-screen-orientation-change.html – MobileCushion

回答

相關問題