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

Android无需SharedPreference实现按返回键Activity数据不丢失

Activity按返回键回退时页面数据丢失解决方案

不需要使用SharedPreference,完全可以实现返回时保留Activity1的原有数据。

正常情况下,从Activity1启动Activity2后,Activity1会被压入返回栈进入停止状态,按设备返回键时系统会将栈内留存的Activity1实例恢复到前台,数据本应保留。出现数据丢失基本是三类原因:

  • Activity1在后台时因系统内存不足被回收,返回时重建了新的Activity1实例
  • 代码逻辑存在问题:比如在onResume等生命周期里无条件重置页面数据,或是启动Activity时加了清空栈的Flag
  • 启动Activity用了错误的Context,导致系统栈管理异常,原有Activity1实例被销毁

方案1:使用原生瞬时状态保存API(无额外依赖,兼容所有Android版本)

这是Android官方提供的专门用于存储页面临时状态的能力,不需要做任何持久化写入。

  1. 在Activity1中重写onSaveInstanceState方法,在系统回收Activity前把需要保留的页面数据存入Bundle:
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
    // 按需存入所有需要保留的页面数据,比如输入框内容、列表数据、选中状态等
    outState.putString("et_input", editText.getText().toString());
    outState.putInt("selected_tab", currentTabPos);
    outState.putParcelableArrayList("list_data", dataList);
}
  1. 在Activity1的onCreate方法中判断是否有已保存的状态,有则直接恢复数据,没有则走首次初始化逻辑:
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_first);
    // 先完成控件初始化
    editText = findViewById(R.id.et_input);
    recyclerView = findViewById(R.id.rv_list);

    if (savedInstanceState != null) {
        // 取出之前保存的数据恢复页面
        String savedInput = savedInstanceState.getString("et_input");
        int savedTab = savedInstanceState.getInt("selected_tab");
        ArrayList<MyData> savedList = savedInstanceState.getParcelableArrayList("list_data");
        
        editText.setText(savedInput);
        dataList.clear();
        if (savedList != null) dataList.addAll(savedList);
        adapter.setSelectedPos(savedTab);
        adapter.notifyDataSetChanged();
    } else {
        // 首次进入页面的正常初始化逻辑
        loadDefaultData();
    }
}

方案2:使用ViewModel持有页面数据(适配Jetpack架构,代码更简洁)

如果项目接入了Jetpack组件,优先用ViewModel存储页面数据。ViewModel的生命周期独立于Activity实例,只要Activity1还在返回栈中,ViewModel持有的数据就不会被销毁,不需要手动写Bundle存取逻辑。

  1. 定义对应Activity1的ViewModel类,所有页面状态数据都存在ViewModel中:
public class FirstViewModel extends ViewModel {
    public MutableLiveData<String> inputText = new MutableLiveData<>("");
    public MutableLiveData<List<MyData>> pageList = new MutableLiveData<>(new ArrayList<>());
    public int currentTab = 0;
}
  1. 在Activity1中获取ViewModel实例,所有数据操作都针对ViewModel进行,UI观察ViewModel的数据变化自动更新:
private FirstViewModel viewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_first);
    viewModel = new ViewModelProvider(this).get(FirstViewModel.class);
    // 初始化控件
    editText = findViewById(R.id.et_input);
    recyclerView = findViewById(R.id.rv_list);

    // 观察数据变化更新UI
    viewModel.inputText.observe(this, text -> editText.setText(text));
    viewModel.pageList.observe(this, list -> adapter.updateData(list));

    // 用户操作时直接更新ViewModel中的数据
    editText.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            viewModel.inputText.setValue(s.toString());
        }
        @Override
        public void afterTextChanged(Editable s) {}
    });
}

如果需要兼容系统在后台杀死进程的场景,可以给ViewModel配合SavedStateHandle使用,无需额外写onSaveInstanceState逻辑即可自动保存恢复状态。


必须修正的现有代码问题

你当前的启动代码存在两个容易引发栈异常的问题,必须修改:

  1. 启动Activity不要用Application Context,换成当前Activity的Context,避免栈管理异常导致Activity1被意外销毁
  2. 类名遵循Java大驼峰命名规范,不要用全小写的类名,避免混淆或编译异常

修改后的启动代码如下:

// 把secondactivity改成大驼峰命名的SecondActivity
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
startActivity(intent);

额外检查项:

  • 不要在Activity1的onResume方法里无条件重置页面数据、重新加载初始数据,否则每次回到前台数据都会被覆盖
  • 启动Activity2的Intent不要加FLAG_ACTIVITY_CLEAR_TOP、FLAG_ACTIVITY_NO_HISTORY、FLAG_ACTIVITY_CLEAR_TASK这类会清空Activity栈的Flag,否则返回时会创建新的Activity1实例,原有数据自然丢失

内容的提问来源于stack exchange,提问作者Brimo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 07:01:25