以下是Fragment
我用来显示简单秒表的精简版。该应用程序在平板电脑上运行良好。但是,在手机上,方向变化会导致在新活动中重新创建片段,我遇到了内存泄漏。
public class TimerFragment extends BaseFragment {
private static final int MESSAGE_UPDATE_TEXT = 0;
private TextView text;
private static final String KEY_START_TIME = "KEY_START_TIME";
private static final String KEY_ELAPSED_TIME = "KEY_ELAPSED";
private long startTime;
private long elapsedTime;
private static boolean running;
private final TimerHandler handler = new TimerHandler(this);
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
setHasOptionsMenu(true);
setUpHomeButton(false);
View view = inflater.inflate(R.layout.fragment_timer, container, false);
text = (TextView) view.findViewById(R.id.timerText);
if(savedInstanceState != null) {
startTime = savedInstanceState.getLong(KEY_START_TIME);
elapsedTime = savedInstanceState.getLong(KEY_ELAPSED_TIME);
}
if(running) {
handler.removeCallbacks(timer);
handler.postDelayed(timer, 0);
}
updateText();
return view;
}
private void updateText() {
if(elapsedTime == 0L) {
text.setText("0:00");
return;
}
int sec = (int) (elapsedTime / 1000);
int min = sec / 60;
sec = sec % 60;
text.setText(min + ":" + sec);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
handler.removeCallbacks(timer);
outState.putLong(KEY_START_TIME, startTime);
outState.putLong(KEY_ELAPSED_TIME, elapsedTime);
}
private final Runnable timer = new Runnable() {
@Override
public void run() {
long now = System.currentTimeMillis();
elapsedTime = now - startTime;
running = true;
handler.postDelayed(this, 1000);
handler.sendEmptyMessage(MESSAGE_UPDATE_TEXT);
}
};
private static class TimerHandler extends Handler {
private final WeakReference<TimerFragment> weakFragment;
public TimerHandler(TimerFragment f) {
weakFragment = new WeakReference<TimerFragment>(f);
}
@Override
public void handleMessage(Message msg) {
TimerFragment fragment = weakFragment.get();
switch (msg.what) {
case MESSAGE_UPDATE_TEXT:
if(fragment != null) {
fragment.updateText();
}
break;
default:
break;
}
}
}
}
Eclipse MAT 甚至给了我这个:
One instance of "android.os.MessageQueue" loaded by "<system class loader>" occupies 1 529 600 (14,19%) bytes. The memory is accumulated in one instance of "android.os.Message" loaded by "<system class loader>".
Keywords
android.os.Message
android.os.MessageQueue
但是,当我在平板电脑上运行时分析内存时,上述内容不会出现(始终单一活动)。
关于如何解决这个问题的任何想法?如果我正确理解了这个问题,我可能不会,我认为当手机上发生方向变化时会创建多个处理程序。
如果我的问题难以理解,请给我一个提示,我会尝试更好地解释。