Android中用SharedPreferences存储多键值对避免数据覆盖的方法
问题根源
原代码存储联系人时,一直用固定的"name"和"number"作为SharedPreferences的键,每次添加新联系人都会覆盖之前的键值,导致只能保留最后一条联系人信息。
修复方案
1. 修改存储逻辑
把联系人的名称作为唯一键,对应的号码作为值存入SharedPreferences,这样每个联系人都是独立的键值对,不会互相覆盖。
修改后的存储代码:
public void addNewContact(View view){ EditText txtName = findViewById(R.id.txt_name); EditText txtNumber = findViewById(R.id.txt_number); String name = txtName.getText().toString().trim(); String number = txtNumber.getText().toString().trim(); // 空值校验,避免存入无效数据 if(name.isEmpty() || number.isEmpty()){ Toast.makeText(this, "名称和号码不能为空", Toast.LENGTH_SHORT).show(); return; } SharedPreferences preferences = getSharedPreferences("contact", Context.MODE_PRIVATE); SharedPreferences.Editor editor = preferences.edit(); // 用联系人名称作为key,号码作为value存储 editor.putString(name, number).apply(); // apply()异步提交,比commit()更高效 Toast.makeText(this, "联系人已添加", Toast.LENGTH_SHORT).show(); // 清空输入框,优化体验 txtName.setText(""); txtNumber.setText(""); }
2. 修改检索逻辑
根据输入的联系人名称,直接从SharedPreferences中获取对应的号码即可,无需再读取固定的"number"键。
修改后的检索代码:
public void findContact(View view){ EditText txtNombre = findViewById(R.id.txt_nombre); String name = txtNombre.getText().toString().trim(); if(name.isEmpty()){ Toast.makeText(this, "请输入联系人名称", Toast.LENGTH_SHORT).show(); return; } SharedPreferences preferences = getSharedPreferences("contact", Context.MODE_PRIVATE); // 根据输入的名称直接获取对应号码 String number = preferences.getString(name, "未找到该联系人"); Toast.makeText(this, name + " : " + number, Toast.LENGTH_SHORT).show(); }
额外优化建议
- 名称唯一性校验:存储前可以检查是否已存在同名联系人,避免意外覆盖(如果需要支持更新联系人则可跳过):
if(preferences.contains(name)){ Toast.makeText(this, "该联系人名称已存在", Toast.LENGTH_SHORT).show(); return; } - 优先使用
apply():异步提交不会阻塞主线程,更适合UI操作场景。
内容的提问来源于stack exchange,提问作者Tuan Do
相关产品推荐
相关产品推荐

