You need to enable JavaScript to run this app. 安卓开发:SharedPreferences存取String与Int数据时,点击获取按钮无法回填已存Int值
优惠活动
大模型
产品
解决方案
定价
更多

安卓开发:SharedPreferences存取String与Int数据时,点击获取按钮无法回填已存Int值

问题根因
  • 核心逻辑错误:在Get方法中判断到Numb键存在时,完全没有读取SharedPreferences中存储的int值,反而硬编码给number控件设置了固定值"0",自然无法取回保存的数字。
  • 常见踩坑点:Android中TextView.setText()没有直接接收int数值的重载方法——如果直接把读取到的int值传给setText(),系统会将这个int值识别为字符串资源ID,尝试查找对应资源时会抛出Resources$NotFoundException异常,这也是很多人无法正确把存储的int值回填到文本框的核心原因。
  • 冗余逻辑:在onCreate、Get、clear方法中重复初始化控件、重复获取SharedPreferences实例,既增加无意义的性能消耗,也容易造成逻辑混乱。
  • 潜在崩溃风险:Save方法中直接调用Integer.parseInt()解析输入框内容,如果用户未输入有效数字,会直接触发NumberFormatException导致应用崩溃。
修正实现
  • 移除所有重复的控件初始化、SharedPreferences获取代码,仅在onCreate中完成一次全局初始化即可。
  • 修改Get方法的数字读取逻辑:先通过sharedpreferences.getInt()取出存储的int值,使用String.valueOf()将其转为字符串后再设置给number控件,避免int值被误判为资源ID。
  • 对数字输入框的解析逻辑增加非空校验,规避崩溃风险。
修正后的代码示例
public class MainActivity extends AppCompatActivity {
    SharedPreferences sharedpreferences;
    TextView name;
    TextView email;
    TextView number;
    public static final String Name = "nameKey";
    public static final String Email = "emailKey";
    public static final String Numb = "numbKey";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 全局统一初始化控件,无需在其他方法重复调用
        name = findViewById(R.id.etName);
        email = findViewById(R.id.etEmail);
        number = findViewById(R.id.number);
        // 全局统一获取SharedPreferences实例
        sharedpreferences = getSharedPreferences("mypref", Context.MODE_PRIVATE);
        
        // 启动时自动回填已存储的本地数据
        if (sharedpreferences.contains(Name)) {
            name.setText(sharedpreferences.getString(Name, ""));
        }
        if (sharedpreferences.contains(Email)) {
            email.setText(sharedpreferences.getString(Email, ""));
        }
        if (sharedpreferences.contains(Numb)) {
            number.setText(String.valueOf(sharedpreferences.getInt(Numb, 0)));
        }
        Toast.makeText(getApplicationContext(),"It just saves the data",Toast.LENGTH_SHORT).show();
    }

    public void Save(View view) {
        String n = name.getText().toString().trim();
        String e = email.getText().toString().trim();
        // 增加输入校验,避免空值/非数字导致崩溃
        String inputNum = number.getText().toString().trim();
        if (TextUtils.isEmpty(inputNum)) {
            Toast.makeText(this, "请输入有效数字", Toast.LENGTH_SHORT).show();
            return;
        }
        int numb = Integer.parseInt(inputNum);
        SharedPreferences.Editor editor = sharedpreferences.edit();
        editor.putString(Name, n);
        editor.putString(Email, e);
        editor.putInt(Numb, numb);
        editor.apply(); // 相比commit,apply为异步写入,更推荐日常使用
        Toast.makeText(getApplicationContext(),"Number was:"+numb,Toast.LENGTH_SHORT).show();
    }

    public void Get(View view) {
        // 直接使用全局初始化的控件和SharedPreferences实例即可
        if (sharedpreferences.contains(Name)) {
            name.setText(sharedpreferences.getString(Name, ""));
        }
        if (sharedpreferences.contains(Email)) {
            email.setText(sharedpreferences.getString(Email, ""));
        }
        if (sharedpreferences.contains(Numb)) {
            // 正确读取存储的int值,转为字符串后设置给控件
            int savedNum = sharedpreferences.getInt(Numb, 0);
            number.setText(String.valueOf(savedNum));
        }
    }

    public void clear(View view) {
        // 清除SharedPreferences存储的内容,同时清空控件显示
        sharedpreferences.edit().clear().apply();
        name.setText("");
        email.setText("");
        number.setText("");
    }

}

说明:原来的editor.commit()是同步写入磁盘,适合需要确保写入成功的极端场景,日常开发推荐使用editor.apply(),它会先更新内存值再异步写盘,不会阻塞主线程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.05 05:06:04