如何用SharedPreferences实现测验数据的累加存储与持久化?
解决测验数据累加统计及持久化问题
核心问题修复:实现正确的累加逻辑
你当前的saveData方法直接覆盖了原有数据,要实现累加,需要先读取已保存的累计值,加上本次测验的数值后再写入。修改后的代码如下:
public void saveData() { // 获取SharedPreferences实例 SharedPreferences quizData = getSharedPreferences("Quiz Stats", Context.MODE_PRIVATE); // 读取当前累计的统计数据(默认值为0) int currentTotal = quizData.getInt("Total questions", 0); int currentCorrect = quizData.getInt("Correct Answers", 0); int currentWrong = quizData.getInt("Wrong Answers", 0); // 累加本次测验数据 int newTotal = currentTotal + questionsLength; int newCorrect = currentCorrect + correctAnswerCount; int newWrong = currentWrong + wrongAnswerCount; // 写入更新后的累计数据 SharedPreferences.Editor editor = quizData.edit(); editor.putInt("Total questions", newTotal); editor.putInt("Correct Answers", newCorrect); editor.putInt("Wrong Answers", newWrong); editor.apply(); }
解决重复累加问题
切换Fragment时重复累加,本质是saveData被多次调用了。你需要:
- 确保
saveData仅在单次测验完全结束后调用一次,比如用户完成所有题目并点击「提交结果」按钮时触发,而非在Fragment的onResume/onCreate等生命周期方法中调用。 - 可以在测验页面添加一个标记位(如
private boolean isStatsSaved = false;),调用saveData后将其设为true,防止同一测验数据被重复累加。
解决重启应用数据归零问题
之前的重启归零是因为错误删除了累计数据的存储键。SharedPreferences的数据会持久化存储在本地文件中,只要你不主动删除对应的键(如editor.remove("Total questions")),重启应用后数据不会丢失。按照上面的累加逻辑,每次都是更新原有键的值,不会出现归零问题。
代码优化建议
1. 使用常量替代硬编码键名
避免因拼写错误导致的数据读取失败,定义全局常量:
// 可以放在类的顶部作为静态常量 private static final String PREF_QUIZ_STATS = "Quiz Stats"; private static final String KEY_TOTAL_QUESTIONS = "Total questions"; private static final String KEY_CORRECT_ANSWERS = "Correct Answers"; private static final String KEY_WRONG_ANSWERS = "Wrong Answers";
2. 封装SharedPreferences操作
创建一个工具类统一管理统计数据的读写,减少重复代码,提升可维护性:
public class QuizStatsManager { private static final String PREF_NAME = "Quiz Stats"; private static final String KEY_TOTAL = "TotalQuestions"; private static final String KEY_CORRECT = "CorrectAnswers"; private static final String KEY_WRONG = "WrongAnswers"; private final SharedPreferences prefs; public QuizStatsManager(Context context) { prefs = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE); } // 累加并保存本次测验数据 public void addQuizResult(int totalQuestions, int correctCount, int wrongCount) { // 校验数据合理性(总题数应等于答对+答错) if (totalQuestions != correctCount + wrongCount) { Log.e("QuizStats", "数据异常:总题数与答对/答错题数不匹配"); return; } int currentTotal = prefs.getInt(KEY_TOTAL, 0); int currentCorrect = prefs.getInt(KEY_CORRECT, 0); int currentWrong = prefs.getInt(KEY_WRONG, 0); SharedPreferences.Editor editor = prefs.edit(); editor.putInt(KEY_TOTAL, currentTotal + totalQuestions); editor.putInt(KEY_CORRECT, currentCorrect + correctCount); editor.putInt(KEY_WRONG, currentWrong + wrongCount); editor.apply(); } // 获取累计统计数据 public Stats getTotalStats() { int total = prefs.getInt(KEY_TOTAL, 0); int correct = prefs.getInt(KEY_CORRECT, 0); int wrong = prefs.getInt(KEY_WRONG, 0); return new Stats(total, correct, wrong); } // 封装统计数据的内部类 public static class Stats { public final int totalQuestions; public final int correctAnswers; public final int wrongAnswers; public Stats(int total, int correct, int wrong) { this.totalQuestions = total; this.correctAnswers = correct; this.wrongAnswers = wrong; } } }
使用示例:
- 测验结束时保存数据:
QuizStatsManager statsManager = new QuizStatsManager(this); statsManager.addQuizResult(questionsLength, correctAnswerCount, wrongAnswerCount);
- 在Stats Fragment中读取数据:
QuizStatsManager statsManager = new QuizStatsManager(getActivity()); QuizStatsManager.Stats stats = statsManager.getTotalStats(); totalQueNum = stats.totalQuestions; correctAnswersNum = stats.correctAnswers; wrongAnswersNum = stats.wrongAnswers;
3. 增加数据校验
在保存数据前校验总题数与答对/答错题数的一致性,避免存入错误数据。
内容的提问来源于stack exchange,提问作者Sandman
相关产品推荐
相关产品推荐

