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

Android Studio双SharedPreferences使用问题及代码错误排查

你的SharedPreferences代码问题分析与正确用法指南

咱们先拆解你代码里的几个关键问题,再聊聊Android里正确使用多个SharedPreferences的姿势:

一、当前代码存在的问题

1. 异步任务导致的保存时机错误

你调用inTImeWorker.execute(emp_id)后立刻去读取In_time.getText().toString(),但InTImeWorker是异步任务——这时候异步操作还没完成,In_time的文本内容根本还没更新!所以你存到SharedPreferences里的要么是空字符串,要么是旧的无效值,这是最核心的问题。

2. 重复调用提交方法

你同时调用了editor.apply()和editor.commit(),这完全没必要:

  • apply()是异步提交,不会阻塞主线程,大部分场景推荐用这个;
  • commit()是同步提交,会返回布尔值告诉你是否提交成功,但会阻塞当前线程。
    选其中一个就够了,同时调用只会做重复工作。

3. 变量命名易混淆

你两次获取SharedPreferences都用了同一个sp变量,虽然语法上没问题,但容易让代码逻辑变混乱,后续维护时可能搞混哪个是哪个。

二、正确使用两个SharedPreferences的方法

Android里的SharedPreferences是靠唯一的名称来区分的,不同名称对应不同的存储文件,完全独立不会互相干扰。针对你的场景,咱们修改代码如下:

修改后的示例代码

public void OnAttendLogin(View view) {
    // 1. 获取登录相关的SharedPreferences,用单独的变量名区分
    SharedPreferences spLogin = getSharedPreferences("attendlogin", MODE_PRIVATE);
    String emp_id = spLogin.getString("emp_id", null);

    // 2. 启动异步任务
    InTImeWorker inTImeWorker = new InTImeWorker(this);
    inTImeWorker.delegate = (AsyncResponse) this;
    inTImeWorker.execute(emp_id);

    // 3. 先处理按钮状态,避免重复点击
    out_time_button.setEnabled(true);
    in_time_button.setEnabled(false);
}

// 实现AsyncResponse的回调方法(具体方法名以你的接口定义为准)
@Override
public void onFinish(String inTimeResult) {
    // 异步任务完成后,In_time的文本已经更新,现在才去保存
    // 获取考勤时间相关的SharedPreferences
    SharedPreferences spInTime = getSharedPreferences("InTime", MODE_PRIVATE);
    SharedPreferences.Editor editor = spInTime.edit();
    
    String inTimeText = In_time.getText().toString();
    editor.putString("in_time_sp", inTimeText);
    editor.apply(); // 只保留apply()即可,无需commit()
}

关键优化点说明

  1. 把保存操作移到异步回调里:确保只有当In_time的文本被异步任务更新后,才去读取并保存,保证数据是最新的。
  2. 给不同的SharedPreferences起不同变量名:比如spLogin和spInTime,代码逻辑更清晰,避免变量覆盖混淆。
  3. 移除重复的提交方法:只保留apply(),既高效又不会阻塞主线程。

三、多SharedPreferences使用的通用要点

  • 用唯一名称区分:只要你传入getSharedPreferences()的名称不一样,它们就是完全独立的存储容器,数据不会互相覆盖。
  • 按需获取实例:可以在需要的时候调用getSharedPreferences()获取,也可以在类里提前初始化好实例变量,方便复用。
  • 注意操作时机:涉及异步操作(比如网络请求、AsyncTask)时,一定要等数据准备完毕再执行SharedPreferences的写入操作。
  • 合理选择提交方式:不需要知道提交结果时用apply();需要确认是否提交成功(比如敏感数据)时用commit(),但要注意避免在主线程频繁调用commit()导致卡顿。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:54:00