Android返回首个Activity时保留TextView数据及阈值延迟生效问题
解决思路与实现方案
嘿,这个需求其实很好解决,核心就是要区分当前生效的阈值和待生效的新阈值——我们不需要用持久化的SharedPreferences,也不用依赖仅处理配置变化的onSavedInstanceState,直接在第一个Activity里维护两个变量,再配合Activity间的结果传递就能搞定!
核心逻辑
- 第一个Activity里保存两个变量:
currentThreshold:当前正在使用的阈值,计数逻辑完全依赖它pendingThreshold:暂存从第二个Activity返回的新阈值,只有点击「重置」按钮才会替换currentThreshold
- 跳转第二个Activity时,把当前的
pendingThreshold传过去作为默认值;返回时接收用户修改后的新值,更新pendingThreshold - 点击「重置」按钮时,将
pendingThreshold赋值给currentThreshold,让新阈值正式生效
具体代码实现(以Kotlin为例)
1. 第一个Activity的核心代码
首先用Activity Result API(替代已废弃的startActivityForResult)来处理返回结果:
import android.app.Activity import android.content.Intent import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import androidx.activity.result.contract.ActivityResultContracts import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { // 初始化阈值:当前生效阈值和待生效阈值都为5 private var currentThreshold = 5 private var pendingThreshold = 5 private var count = 0 // 注册Activity返回结果监听 private val getNewThreshold = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> if (result.resultCode == Activity.RESULT_OK) { // 获取从第二个Activity返回的新阈值 val newThreshold = result.data?.getIntExtra("NEW_THRESHOLD", currentThreshold) ?: currentThreshold pendingThreshold = newThreshold // 可以给用户提示:"阈值已修改,点击重置生效" } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) updateCountDisplay() // 跳转至第二个Activity的按钮点击事件 btn_go_to_second.setOnClickListener { val intent = Intent(this, SecondActivity::class.java) // 把当前待生效的阈值传过去,作为第二个Activity的默认显示值 intent.putExtra("CURRENT_PENDING", pendingThreshold) getNewThreshold.launch(intent) } // 计数按钮逻辑:仅在当前计数小于生效阈值时累加 btn_count.setOnClickListener { if (count < currentThreshold) { count++ updateCountDisplay() } } // 重置按钮逻辑:让待生效阈值正式替换当前生效阈值 btn_reset.setOnClickListener { currentThreshold = pendingThreshold // 如果需要的话,这里可以重置计数(比如当前计数超过新阈值时) // if (count > currentThreshold) count = currentThreshold updateCountDisplay() } } // 更新计数和阈值的显示 private fun updateCountDisplay() { tv_count.text = "当前计数:$count / 生效阈值:$currentThreshold\n待生效阈值:$pendingThreshold" } }
2. 第二个Activity的核心代码
负责接收默认阈值、让用户修改,然后返回新阈值:
import android.app.Activity import android.content.Intent import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import kotlinx.android.synthetic.main.activity_second.* class SecondActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_second) // 获取从第一个Activity传递过来的默认阈值 val defaultThreshold = intent.getIntExtra("CURRENT_PENDING", 5) et_threshold.setText(defaultThreshold.toString()) // 确认按钮:返回新阈值并关闭页面 btn_confirm.setOnClickListener { val newThreshold = et_threshold.text.toString().toIntOrNull() ?: defaultThreshold val resultIntent = Intent() resultIntent.putExtra("NEW_THRESHOLD", newThreshold) setResult(Activity.RESULT_OK, resultIntent) finish() } // 处理返回键:同样返回用户修改后的阈值 override fun onBackPressed() { val newThreshold = et_threshold.text.toString().toIntOrNull() ?: defaultThreshold val resultIntent = Intent() resultIntent.putExtra("NEW_THRESHOLD", newThreshold) setResult(Activity.RESULT_OK, resultIntent) super.onBackPressed() } } }
为什么你的之前方案不行?
- SharedPreferences:它是持久化存储,会把新阈值永久保存,哪怕用户重启APP也会保留,不符合「仅点击重置才生效」的临时需求
- onSavedInstanceState:它的设计目的是保存Activity因配置变化(比如旋转屏幕)被销毁时的状态,不是用来传递跨Activity的临时数据,所以返回时不会帮你保留新阈值
进阶优化:用ViewModel避免数据丢失
如果担心第一个Activity因内存不足被销毁导致数据丢失,可以把currentThreshold、pendingThreshold和count放到ViewModel里,这样即使Activity重建,数据也能保留:
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel class MainViewModel : ViewModel() { val currentThreshold = MutableLiveData(5) val pendingThreshold = MutableLiveData(5) val count = MutableLiveData(0) }
然后在第一个Activity里通过viewModels()获取ViewModel,把所有变量替换成LiveData即可。
内容的提问来源于stack exchange,提问作者Niiks
相关产品推荐
相关产品推荐

