Android Kotlin开发:XO游戏两大技术问题求助
XO游戏开发问题解答
问题1:Activity2跳转Activity3再返回后数据变为null
原因
当Activity2跳转到Activity3后,若系统因内存不足等原因回收了Activity2,从Activity3返回时Activity2会重新创建,此时原intent中的额外数据可能丢失。加上你当前仅在onCreate中从intent取数据,未做状态保存,一旦Activity重建就会出现数据为null的情况。
解决办法
方法1:用savedInstanceState保存状态
在Activity2中重写状态保存方法,确保重建时能恢复数据:
class TwoPlayers : AppCompatActivity() { private var extraOne: String = "" private var extraTwo: String = "" override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.players_two) val xwinstxt = findViewById<TextView>(R.id.xwinstxt) val owinstxt = findViewById<TextView>(R.id.owinstxt) // 优先从savedInstanceState恢复,无数据则从intent获取 if (savedInstanceState != null) { extraOne = savedInstanceState.getString("player_one", "") extraTwo = savedInstanceState.getString("player_two", "") } else { extraOne = intent.getStringExtra("firstplayername") ?: "" extraTwo = intent.getStringExtra("secondplayername") ?: "" } xwinstxt.text = extraOne owinstxt.text = extraTwo } override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) // 保存玩家名称到Bundle outState.putString("player_one", extraOne) outState.putString("player_two", extraTwo) } }
方法2:用ViewModel存储数据
ViewModel生命周期不受Activity重建影响,适合跨界面状态保存:
先创建ViewModel类:
class PlayerViewModel : ViewModel() { var playerOneName: String = "" var playerTwoName: String = "" }
Activity1中设置数据:
fun startgame(view: View) { val editone = findViewById<EditText>(R.id.playerone) val playerone = editone.text.toString() val edittwo = findViewById<EditText>(R.id.playertwo) val playertwo = edittwo.text.toString() val viewModel = ViewModelProvider(this)[PlayerViewModel::class.java] viewModel.playerOneName = playerone viewModel.playerTwoName = playertwo val intent = Intent(this, TwoPlayers::class.java) startActivity(intent) }
Activity2中获取数据:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.players_two) val xwinstxt = findViewById<TextView>(R.id.xwinstxt) val owinstxt = findViewById<TextView>(R.id.owinstxt) val viewModel = ViewModelProvider(this)[PlayerViewModel::class.java] val extraOne = viewModel.playerOneName val extraTwo = viewModel.playerTwoName xwinstxt.text = extraOne owinstxt.text = extraTwo }
问题2:从Activity2返回Activity1时刷新并重置内容
解决办法:使用registerForActivityResult
在Activity1中注册回调,接收Activity2的返回事件并执行重置逻辑:
步骤1:Activity1中注册回调
class Activity1 : AppCompatActivity() { private val startForResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { _ -> // 返回后执行重置操作 val editone = findViewById<EditText>(R.id.playerone) val edittwo = findViewById<EditText>(R.id.playertwo) editone.text.clear() edittwo.text.clear() // 其他需要重置的UI或数据逻辑 } fun startgame(view: View) { val editone = findViewById<EditText>(R.id.playerone) val playerone = editone.text.toString() val edittwo = findViewById<EditText>(R.id.playertwo) val playertwo = edittwo.text.toString() val intent = Intent(this, TwoPlayers::class.java) intent.putExtra("firstplayername", playerone) intent.putExtra("secondplayername", playertwo) startForResult.launch(intent) } }
步骤2:(可选)Activity2中主动设置返回结果
若需要主动触发返回并标记状态,可在Activity2中添加:
fun onBackClick(view: View) { setResult(RESULT_OK) finish() }
如果是系统返回键,默认会触发回调,此时可根据resultCode调整逻辑,比如仅在RESULT_OK时重置。
内容的提问来源于stack exchange,提问作者onlyforquestions
相关产品推荐
相关产品推荐

