我有一个应用程序,它的布局有~150个editText和一个mainActivity,每个editText都有一个onClickListener,还有一个按钮循环遍历它们并清除它们。
应用程序运行良好,并且没有进行任何重大更改,我现在每次启动应用程序时都会收到以下logCat错误:
Out of memory on a 2903056-byte allocation.
我在这里做的任何明显的不良做法是否会导致记忆丧失?
我在下面的一些代码作为说明(这显然重复了很多次)
box0101.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
txtHint.setText(hintPrefix + onOneClick);
return false;
}
});
box0301.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
txtHint.setText(hintPrefix + onOneClick);
return false;
}
});
box0401.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
txtHint.setText(hintPrefix + onOneClick);
return false;
}
});
box0501.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
txtHint.setText(hintPrefix + onOneClick);
return false;
}
});
box0601.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
txtHint.setText(hintPrefix + onOneClick);
return false;
}
});
还有一些按钮点击侦听器会引发一些循环
btnClear.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
clearBoard();
}
});
public void clearBoard() {
final int ROW_COUNT = 14;
final int COL_COUNT = 9;
final String ROWS[] = {"01","02","03","04","05","06","07","08","09","10","11","12","13","14","15"};
final String COLS[] = {"01","02","03","04","05","06","07","08","09","10"};
for(int i=0; i<ROW_COUNT; i++) {
for(int j=0; j<COL_COUNT; j++) {
String a = ROWS[i];
String b = COLS[j];
int editTextId = getResources().getIdentifier("box" + a + b , "id", getPackageName());
EditText et=(EditText)findViewById(editTextId);
et.setText("");
}
}
}
正如 @alex.veprik 提到的:尝试使用一个OnClickListener
,并将其分配给所有EditText
对象。如果您为每个EditText
对象创建一个新OnClickListener
,尽管它们都执行相同的操作,这将占用大量内存。
示例)
View.OnTouchListener boxListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
txtHint.setText(hintPrefix + onOneClick);
return false;
}
});
//boxes is a list of all your boxes
for(int i=0; i < boxes.size(); i++) {
boxes.get(i).setOnTouchListener(boxListener);
}
将 EditText
对象的创建放在循环中,并在成员变量中仅存储所有框的列表也可能是明智的。因此,您现在只需要一个变量用于列表,同时保留所有引用,而不是 150 个变量。(这不会影响你的内存问题,但它是很好的代码风格)
List<EditText> boxes = new ArrayList<EditText>();
for (int i = 0; i < NBR_OF_BOXES; i++) {
boxes.add(new EditText());
}
正如@zapl建议的那样,使用内存探查器也可能很好。
onTouch() 方法,而是使用 switch 语句为每个 EditText 创建一个大小写,使用 EditText ID
public boolean onTouch(View v, MotionEvent event) {
switch(v.getId())
{
case R.id.editTextID:
//Do something, etc
}
return false;
}