我认为我的应用正在占用额外的内存,而垃圾回收器应该能够重新分配。我不知道它们是否会被视为内存泄漏,但我已经注意到了可能存在问题的两个地方:
从应用程序启动开始,连续将我的设备从纵向旋转到横向,然后再从横向旋转到纵向……每次旋转后,累计增加 300KB 的内存使用量。
有2个输入时,每次按钮单击,累计增加 30KB 的内存使用量。
问题在于,只要应用程序仍然在视图中,内存就不会被释放。
例如:将设备旋转10次,并单击按钮50次 -> 消耗4.5MB内存。如果我让应用程序保持打开状态并且1小时不做任何操作,则我的应用程序仍将消耗4.5MB的内存;即使很多内存应该在大约59分钟前被释放! 我关心的是为什么当应用程序始终处于视图中时,内存从未被释放? 我对这个工作方式理解错误吗?
注意:应用程序名为 Contrived Calculator
从应用程序启动开始,连续将我的设备从纵向旋转到横向,然后再从横向旋转到纵向……每次旋转后,累计增加 300KB 的内存使用量。
有2个输入时,每次按钮单击,累计增加 30KB 的内存使用量。
问题在于,只要应用程序仍然在视图中,内存就不会被释放。
例如:将设备旋转10次,并单击按钮50次 -> 消耗4.5MB内存。如果我让应用程序保持打开状态并且1小时不做任何操作,则我的应用程序仍将消耗4.5MB的内存;即使很多内存应该在大约59分钟前被释放! 我关心的是为什么当应用程序始终处于视图中时,内存从未被释放? 我对这个工作方式理解错误吗?
注意:应用程序名为 Contrived Calculator
代码
用户界面
public class Calculator extends AppCompatActivity implements ICalculatorInteraction {
private EditText txtNumber1, txtNumber2, txtResult;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_calculator);
Button btnAdd = (Button) findViewById(R.id.btnAddition);
Button btnSub = (Button) findViewById(R.id.btnSubtract);
Button btnMul = (Button) findViewById(R.id.btnMultiple);
Button btnDiv = (Button) findViewById(R.id.btnDivide);
txtNumber1 = (EditText) findViewById(R.id.txtNumber1);
txtNumber2 = (EditText) findViewById(R.id.txtNumber2);
txtResult = (EditText) findViewById(R.id.txtResult);
btnAdd.setOnClickListener(new OperationClick(Add).listenerOn(this));
btnSub.setOnClickListener(new OperationClick(Subtract).listenerOn(this));
btnMul.setOnClickListener(new OperationClick(Multiply).listenerOn(this));
btnDiv.setOnClickListener(new OperationClick(Divide).listenerOn(this));
@Override
public String getFirstNumber() { return valueOf(this.txtNumber1); }
@Override
public String getSecondNumber() { return valueOf(this.txtNumber2); }
@Override
public void updateResult(String result) { this.txtResult.setText(result); }
private String valueOf(EditText textbox) {
String text = textbox.getText().toString();
if (text.isEmpty()) {
textbox.setText("0");
return "0";
}
return text;
}
// default android activity methods
}
Listener Logic
public class OperationClick {
private BinaryOperation operation; // ENUM - advanced
private View.OnClickListener listener;
public OperationClick(final BinaryOperation operation) { this.operation = operation; }
public View.OnClickListener listenerOn(final ICalculatorInteraction UI) {
if (listener != null) return listener;
return listener = new View.OnClickListener() {
@Override
public void onClick(View v) {
double num1, num2, total;
String result, sign;
num1 = Double.parseDouble(UI.getFirstNumber());
num2 = Double.parseDouble(UI.getSecondNumber());
total = operation.execute(num1, num2);
sign = operation.getSymbol();
result = String.format("%s %s %s = %s", num1, sign, num2, total);
UI.updateResult(result);
}
};
}
计算逻辑
public enum BinaryOperation {
Add ("+") { @Override double execute(final double a, final double b) { return a + b; } },
Subtract ("-") { @Override double execute(final double a, final double b) { return a - b; } },
Multiply ("×") { @Override double execute(final double a, final double b) { return a * b; } },
Divide ("÷") { @Override double execute(final double a, final double b) { return a / b; } };
private final String symbol;
abstract double execute(double a, double b);
BinaryOperation(String symbol) { this.symbol = symbol; }
public String getSymbol() { return this.symbol; }
}