【发布时间】:2011-12-09 16:26:38
【问题描述】:
我刚刚开始使用 Android。我尝试了具有方向更改的应用程序。
我正面临位图大小超出 VM 预算的问题。在stackoverflow中浏览了许多帖子,无法找出问题所在。异常在 setContentView(R.layout.level1);在创建。当我改变方向时会发生这种情况。
我已经尝试了所有论坛和 stackoverflow,但无法弄清楚。过去 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));
}
- 在 onCreate 方法中,创建一个可绘制列表并在首次加载时对其进行初始化。
- 使用Thread随机设置按钮图片背景
- 调用 unbindDrawables() 方法 onDestroy 以便在方向更改时从内存中删除旧视图。
- hand.removeCallbacks(runThread) 也在 onPause 方法中被调用
- 在 onRetainNonConfigurationInstance() 中返回 null
我已经解决了这个问题。 小错误导致了这个大问题。我在 Handler 中使用了 Thread 而不是 Runnable。因此,removeCallback 没有按预期工作。
【问题讨论】:
-
您的清单文件设置是什么? ,您是将方向更改传递给 Activity 以手动处理,还是采用老式且经常崩溃的破坏和重建?
-
您正在加载的图片尺寸是多少?您正在加载多少张图片?正如克里斯所说,在方向变化中,所有活动都被破坏并重新加载。问题可能是上一个方向的图像仍在加载,而下一个方向的图像正在加载。应用程序崩溃,因为 WM 内存不足。调用 unbindDrawables() System.gc() 并不能确保在加载下一个图像之前卸载图像。
-
我没有手动处理方向更改。正如 Jobesu 所说,问题可能是 unbindDrawables() 和 System.gc() 可能没有卸载以前的图像。 UI 有一个 bg 颜色随机变化的按钮和两个 textview 来显示数据。因此,在每次方向更改时都会创建和销毁一些项目。我不知道如何删除关于方向变化的旧观点。
标签: java android screen-orientation virtual-machine out-of-memory