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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 14:25:23