
本文介绍如何利用 onSaveInstanceState() 和 onCreate() 保存并恢复动态设置文本(X 或 O)的 9 个按钮状态,避免横竖屏切换导致游戏进度丢失。核心是将按钮文本序列化为字符串并存入 Bundle,再按索引还原。
本文介绍如何利用 `onsaveinstancestate()` 和 `oncreate()` 保存并恢复动态设置文本(x 或 o)的 9 个按钮状态,避免横竖屏切换导致游戏进度丢失。核心是将按钮文本序列化为字符串并存入 bundle,再按索引还原。
在 Android 开发中,Activity 因屏幕旋转被销毁重建时,视图状态不会自动保留——尤其是像井字棋(Tic-Tac-Toe)这类依赖用户交互动态更新 Button 文本("X" / "O" / "")的场景。直接将状态绑定在 View 上(如 button.getText())无法跨生命周期存活,必须通过 savedInstanceState 主动保存与恢复。
✅ 推荐方案:用逗号分隔字符串序列化按钮状态
将 Button[9] 的当前文本统一编码为一个轻量、可解析的字符串(例如 "X,-,O,X,O,-,-,X,O"),其中 - 表示空按钮。该格式简洁、无歧义、易于循环生成与解析。
? 保存状态:onSaveInstanceState()
在按钮状态变更后(例如点击逻辑执行完毕),重写 onSaveInstanceState(),遍历所有按钮生成状态字符串:
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
StringBuilder stateBuilder = new StringBuilder();
for (int i = 0; i < buttons.length; i++) {
String text = buttons[i].getText().toString().trim();
stateBuilder.append(text.isEmpty() ? "-" : text);
if (i < buttons.length - 1) stateBuilder.append(",");
}
outState.putString("board_state", stateBuilder.toString());
}? 恢复状态:onCreate() 中初始化后还原
注意:必须在 setContentView() 且所有 buttons[] 初始化完成后(例如 findViewById(R.id.btn_0) 赋值完毕)再执行恢复逻辑:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initButtons(); // 确保 buttons[] 已正确初始化
if (savedInstanceState != null) {
String savedState = savedInstanceState.getString("board_state");
if (savedState != null) {
String[] states = savedState.split(",");
for (int i = 0; i < Math.min(buttons.length, states.length); i++) {
String val = states[i].trim();
if ("X".equals(val) || "O".equals(val)) {
buttons[i].setText(val);
buttons[i].setTextColor(
"X".equals(val) ? Color.parseColor("#ff4a4a") : Color.parseColor("#70FFEA")
);
} else {
buttons[i].setText("");
}
}
}
}
}⚠️ 关键注意事项
-
不要在
onRestoreInstanceState()中恢复 UI:它可能在onCreate()之前调用,此时 View 尚未 inflate,易引发NullPointerException。统一在onCreate()中处理更安全。 -
避免冗余存储:无需为每个按钮单独存 Key(如
"btn_0","btn_1"),单 Key 字符串更高效。 -
状态一致性:确保
gameState[]数组也同步恢复(可在恢复按钮文本后,根据"X"/"O"重置gameState[i] = 0/1)。 -
替代方案提醒:对于复杂应用,建议采用
ViewModel+SavedStateHandle实现更健壮的状态持久化,但对简单旋转场景,Bundle 方案已足够轻量可靠。
通过以上实现,无论用户如何旋转屏幕,九宫格的每一步落子都将毫秒级无缝还原,保障流畅的游戏体验。

















