You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 11:57:47