【问题标题】:SharedPreferences issue - Losing last saved valueSharedPreferences 问题 - 丢失上次保存的值
【发布时间】:2017-06-23 18:01:05
【问题描述】:

我遇到了一个奇怪的问题,我的应用程序从用户输入中收集了一些数据并将其保存在 SQLite 数据库中。我还有一个持续运行的服务(START_STICKY),它每 30 分钟通过查看 SQLite DB 来检查用户的新更新。如果添加了新记录,则会使用 AsyncTask 将其发送到我的服务器以上传数据。为了跟踪已上传的记录,我在 SharedPreferences 中存储了一个 int 值。因此,这从 0 值开始,在每次上传时,我都会在我的 SQLite DB 上获得最后一个索引,并将其保存在我的 SharedPreferences 中。如果启动应用程序后我向服务器发送了 10 条记录,我将在 SharedPreferences 上保存“10”,并在下一次更新(30 分钟后)中选择索引大于 10 的所有记录。

一切正常,但有时 Android 会终止我的服务,可能是为了优化内存,然后服务重新启动 (START_STICKY) 并且应用程序继续工作。只有在这种情况下,有时我会丢失 SharedPreferences 上最后保存的值,并且由于我使用此值作为参考来选择新记录并将其上传到我的服务器,因此我的应用程序在发生这种情况时会发送重复信息...... 我将在 SharedPreferences 上保存 int 值的方式从“apply()”方法更改为“commit()”,因为最后一个方法将信息直接保存在文件中,但问题没有解决。

欢迎任何关于如何处理此问题或其他方法的想法。

我的 SharedPreferences 类如下所示:

public class MySharedPreferences {
    private SharedPreferences sharedPref;

    public MySharedPreferences(Context context) {
        sharedPref = context.getSharedPreferences("com.mypackage", Context.MODE_PRIVATE);
    }

    public void setIndex(int n) {
        //sharedPref.edit().putInt("index", n).apply();
        SharedPreferences.Editor editor = sharedPref.edit();
        editor.putInt("index", n);
        editor.commit();
    }

    public int getIndex() {
        return sharedPref.getInt("index", 0);
    }
}

我的 SharedPreferences 对象在 Service onCreate 方法上被实例化:

MySharedPreferences mySharedPref = new MySharedPreferences(context);

这是在我的服务中运行的 AsyncTask 示例:

private class UpdateData extends AsyncTask<String, Void, Void> {
    @Override
    protected Void doInBackground(String... strings) {
        try {
            String response = utils.postDataHttps("https://my_url.com", params);
            if (response.equals("OK")) {
                // Access SQLite DB and select last index
                // by using this query: SELECT id FROM my_table ORDER BY id DESC LIMIT 1;
                int lastIndex = myDb.getLastIndex(); 
                // Set last index on SharedPreferences:
                mySharedPref.setIndex(lastIndex);
            } 
        } catch (Exception e) {
            Log.e(LOG_TAG, "UpdateData.doInBackground() - Exception: " + e.getMessage() + "\n" + Log.getStackTraceString(e));
        }
        return null;
    }
}

提前致谢!

【问题讨论】:

    标签: java android sqlite sharedpreferences


    【解决方案1】:

    您确定在 ondestroy 之后没有清理您的 sharedpreference 数据吗?

    更新 尝试使用应用程序的上下文而不是活动的上下文。

    【讨论】:

    • 我确定我没有清理这些值。我只是在应用重启后丢失了最后一次更新,之前更​​新的值仍然存在,该值永远不会为零。不过还是谢谢!
    • 您丢失了最后一次更新吗?来自数据库还是 sp?
    • 我丢失了保存在 SharedPreferences 上的最后更新。在每次更新服务器时,我首先检查我的 SharedPreferences 值以查看我保存的最后一个索引是什么,因为它代表我发送到服务器的 SQLite DB 中的最后一条记录。
    • 假设我在 SharedPreferences 上保存的最后一个索引是 10,然后用户输入了 3 条新记录,那么在下一次更新到服务器时,我将选择 index > 10 的所有记录并将新索引 13 保存在 SharedPreferences 上。所以,下一次对服务器的更新我将检查大于 13 的新记录...问题是:如果在 SharedPreferences 上保存 13 后服务重新启动,则该值将丢失并返回 10,然后我将发送记录 11, 12和13再次(重复)到服务器......对不起,如果我不清楚,英语不是我的第一语言。 @diegoveloper 再次感谢!
    • 我正在从我的应用程序生成的日志中跟踪这个问题,并且大多数时候发生数据丢失时,只有我的服务在后台运行,因为在一些用户输入后,我通过调用“完成”来破坏活动()”。使用应用程序上下文和服务上下文有什么区别,因为我使用第二个来实例化我的 SharedPreferences 对象?再次感谢您!
    【解决方案2】:

    SharedPreference 保存在ApplicationMultiDexApplication 类中。似乎当您的Service 重新创建时,只要您的 android 应用程序安装在应用程序中,“SharedPreferenceis being reset but I am not 100% sure if that is the issue. But if you keep you value as mentioned above, the value will not set to 0 unintentionally. SinceApplicationorMultiDexApplication”类就会保持活动状态。

    【讨论】:

    • 感谢您的意见,但我担心这不是更好的解决方案。我的 SharedPreference 值没有被重置为 0,之前保存的值仍然存在,只是在我的服务重新启动时丢失了最后一次更新。
    【解决方案3】:

    在对 SO 进行新的研究后,我发现了这篇文章:User settings saved in SharedPreferences removed or lost between reloads of app,由于其他选项对我不起作用,我通过创建一个表来将我的引用变量移动到我的 SQLite 数据库中,其中只有一个代表 int 值的记录我需要存储。因此,在我的应用程序的第一次运行中,如果表上没有记录,我只返回 0,并且在将数据发送到服务器后,我使用 INSERT 语句将最后一个索引存储在表的第一行中。每 30 分钟,我只检查存储在该行中的值以确定需要将哪些更新发送到服务器,并在成功上传数据后,我使用 UPDATE 语句再次将最后一个索引存储在我的 int 变量引用中。

    也许这不是最聪明的解决方案,但它就像一个魅力!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-18
      • 2023-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多