Android中如何在Activity与Fragment间存储更新临时共享数据?
解决方案:跨组件临时数据存取
关于SharedPreferences的同步/异步说明
SharedPreferences的写入有两种核心方式:
commit():同步执行,会阻塞当前线程,返回布尔值表示写入是否成功,适合必须确认写入结果的场景。apply():异步执行,先将修改同步到内存,再后台写入磁盘,不会阻塞主线程,无返回值,是日常开发的推荐写入方式。
但SharedPreferences本质是持久化存储,用来存页面间传递的临时数据并不适配,下面提供两种更贴合需求的方案:
方案一:全局单例数据容器(简单直接)
创建一个单例类封装临时数据的get/set方法,整个App生命周期内可全局存取,适合不需要观察数据变化的场景。
代码示例
public class TempDataContainer { // 单例实例 private static TempDataContainer instance; // 临时存储的数据字段 private String userGender; private int userAge; private float userHeight; private float userWeight; // 私有构造,防止外部实例化 private TempDataContainer() {} // 获取单例 public static synchronized TempDataContainer getInstance() { if (instance == null) { instance = new TempDataContainer(); } return instance; } // Getter & Setter 方法 public String getUserGender() { return userGender; } public void setUserGender(String userGender) { this.userGender = userGender; } public int getUserAge() { return userAge; } public void setUserAge(int userAge) { this.userAge = userAge; } public float getUserHeight() { return userHeight; } public void setUserHeight(float userHeight) { this.userHeight = userHeight; } public float getUserWeight() { return userWeight; } public void setUserWeight(float userWeight) { this.userWeight = userWeight; } // 可选:提交到Room后清空临时数据 public void clearTempData() { userGender = null; userAge = 0; userHeight = 0f; userWeight = 0f; } }
使用方式
在FragmentA中存储性别:
// FragmentA.java TempDataContainer.getInstance().setUserGender("男");
在FragmentB中读取性别:
// FragmentB.java String gender = TempDataContainer.getInstance().getUserGender();
在FragmentC中存储身高体重年龄:
// FragmentC.java TempDataContainer.getInstance().setUserAge(25); TempDataContainer.getInstance().setUserHeight(175.5f); TempDataContainer.getInstance().setUserWeight(65.0f);
在FragmentE中读取并保存到Room:
// FragmentE.java TempDataContainer container = TempDataContainer.getInstance(); User user = new User( container.getUserGender(), container.getUserAge(), container.getUserHeight(), container.getUserWeight() ); // 调用Room DAO保存数据 userDao.insertUser(user); // 清空临时数据 container.clearTempData();
方案二:Application级别的ViewModel + LiveData(符合Jetpack架构)
如果需要监听数据变化(比如数据更新后自动刷新UI),可以使用绑定Application生命周期的ViewModel,确保数据在App运行期间不会被销毁,同时利用LiveData实现数据观察。
步骤1:创建全局ViewModel类
import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import android.app.Application; public class GlobalDataViewModel extends AndroidViewModel { // 用MutableLiveData存储可观察的数据 private final MutableLiveData<String> userGender = new MutableLiveData<>(); private final MutableLiveData<Integer> userAge = new MutableLiveData<>(); private final MutableLiveData<Float> userHeight = new MutableLiveData<>(); private final MutableLiveData<Float> userWeight = new MutableLiveData<>(); public GlobalDataViewModel(Application application) { super(application); } // 对外暴露不可变的LiveData,防止外部直接修改 public LiveData<String> getUserGender() { return userGender; } public LiveData<Integer> getUserAge() { return userAge; } public LiveData<Float> getUserHeight() { return userHeight; } public LiveData<Float> getUserWeight() { return userWeight; } // 设置数据的方法 public void setUserGender(String gender) { userGender.setValue(gender); } public void setUserAge(int age) { userAge.setValue(age); } public void setUserHeight(float height) { userHeight.setValue(height); } public void setUserWeight(float weight) { userWeight.setValue(weight); } // 清空数据 public void clearData() { userGender.setValue(null); userAge.setValue(0); userHeight.setValue(0f); userWeight.setValue(0f); } }
步骤2:在组件中获取并使用ViewModel
在FragmentA中存储性别:
// FragmentA.java GlobalDataViewModel viewModel = new ViewModelProvider( this, ViewModelProvider.AndroidViewModelFactory.getInstance(requireActivity().getApplication()) ).get(GlobalDataViewModel.class); viewModel.setUserGender("女");
在FragmentB中观察性别变化并更新UI:
// FragmentB.java GlobalDataViewModel viewModel = new ViewModelProvider( this, ViewModelProvider.AndroidViewModelFactory.getInstance(requireActivity().getApplication()) ).get(GlobalDataViewModel.class); viewModel.getUserGender().observe(getViewLifecycleOwner(), gender -> { // 当性别数据变化时,更新UI if (gender != null) { genderTextView.setText(gender); } });
在FragmentE中读取数据并保存到Room:
// FragmentE.java GlobalDataViewModel viewModel = new ViewModelProvider( this, ViewModelProvider.AndroidViewModelFactory.getInstance(requireActivity().getApplication()) ).get(GlobalDataViewModel.class); // 读取当前数据(不需要观察时直接调用getValue) String gender = viewModel.getUserGender().getValue(); Integer age = viewModel.getUserAge().getValue(); Float height = viewModel.getUserHeight().getValue(); Float weight = viewModel.getUserWeight().getValue(); if (gender != null && age != null && height != null && weight != null) { User user = new User(gender, age, height, weight); userDao.insertUser(user); viewModel.clearData(); }
方案选择建议
- 如果只是简单的临时数据存取,不需要UI自动刷新,优先用全局单例容器,实现成本低,使用简单。
- 如果需要监听数据变化、自动更新UI,或者遵循Jetpack架构规范,选择Application级ViewModel+LiveData。
内容的提问来源于stack exchange,提问作者user18504539
相关产品推荐
相关产品推荐

