【问题标题】:SharedPreferences deleted when the app is killed当应用程序被杀死时,SharedPreferences 被删除
【发布时间】:2015-02-14 11:22:34
【问题描述】:

我有一个可以接收通知(使用 Google Cloud Messaging)并通知用户的服务。在该服务中,我还使用 SharedPreferences 存储云消息传递发送的消息。我将这些消息收集在一个 HashSet 中,并且该 HashSet 及其任何元素都不应该被删除。这很重要,因为我的一项活动必须显示整个消息列表。

这工作正常,除非用户碰巧使用“最近的应用程序”按钮来终止应用程序。当他这样做然后重新启动应用程序时,活动没有检索到一些消息,所以我猜其中一些消息已经以某种方式被删除了。

我没有正确使用 SharedPreferences 吗?我应该怎么做才能避免这种情况?这是我的服务代码:(我的 onHandleIntent 方法的相关部分)

    mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, Notifications.class), 0);
String message=extras.getString("message");

sharedpreferences=this.getSharedPreferences(Constantes.PREFERENCES,Context.MODE_PRIVATE);
Set<String> setMessages= sharedpreferences.getStringSet("SETMESSAGES", new HashSet<String>());
setMessages.add(message);
Editor editor = sharedpreferences.edit();
editor.putStringSet("SETMESSAGES", setMessages);
editor.commit();

//The notification:
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
    .setSmallIcon(R.drawable.icon)
    .setContentTitle("New Notification")
    .setStyle(new NotificationCompat.BigTextStyle().bigText("You got some new message!"))
    .setContentText("You got some new message!")
    .setAutoCancel(true)
    .setDefaults(Notification.DEFAULT_SOUND);

    mBuilder.setContentIntent(contentIntent);
    mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());

【问题讨论】:

  • 之前 editor.putStringSet("SETMESSAGES", setMessages);调用 editor.clear();
  • 是您在“静态”方法中提到的上述代码吗?如果是这样,则很少有已知问题,在此链接中讨论。stackoverflow.com/questions/11480871/…
  • @MeTechnical 不是在静态方法中,这段代码是在onHandleIntent()方法中,还是在onHandleIntent()调用的非静态方法中。 (哪个签名是私有的 void sendNotification(Bundle extras)
  • @Ramesh 看来您的解决方案有效,非常感谢。您是如何找到该解决方案的?如果你愿意,可以回答我的问题,我会选择它作为正确答案。
  • @Kritias 在 SP 中存储消息(实际上是任何频繁更改的数据)并不理想,也不建议使用。相反,您可以为此使用 SQLite 或 Realm,例如 Db。 SP用于存储少量偶尔变化的信息,写SP是一项繁重的操作。

标签: android sharedpreferences google-cloud-messaging


【解决方案1】:

只需在设置 putStringSet 之前添加 editor.clear()。喜欢:

 sharedpreferences=this.getSharedPreferences
                (Constantes.PREFERENCES,Context.MODE_PRIVATE);
 Set<String> setMessages= sharedpreferences.getStringSet
                ("SETMESSAGES", new HashSet<String>());
 setMessages.add(message);
 Editor editor = sharedpreferences.edit();
 editor.clear();
 editor.putStringSet("SETMESSAGES", setMessages);
 editor.commit();

【讨论】:

  • 调用editor.clear(); 将清除所有首选项。你不想这样,是吗?
  • 它似乎适用于新值,但添加 editor.clear,清除 prefs 中保存的任何其他值
  • 解决这个问题的正确方法是首先删除密钥和putstring
【解决方案2】:

感谢 Ramesh 的评论,我解决了这个问题。在editor.putStringSet("SETMESSAGES", setMessages); 之前添加editor.clear(); 修复它。但是我不知道它以前不起作用的原因。

【讨论】:

    【解决方案3】:

    当您更新 StringSet 时,创建 Set 的新副本并更新或删除现有 StringSet,然后添加共享首选项

     String key = "SETMESSAGES";
     sharedpreferences=this.getSharedPreferences
                    (Constantes.PREFERENCES,Context.MODE_PRIVATE);
     Set<String> setMessages= sharedpreferences.getStringSet
                    (key, new HashSet<String>());
     setMessages.add(message);
     Editor editor = sharedpreferences.edit();
     editor.remove(key);
     editor.putStringSet(key, setMessages);
     editor.commit(); 
    

    附:最好调用 editor.apply() 而不是 editor.commit()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-19
      • 1970-01-01
      • 2019-04-08
      • 1970-01-01
      • 1970-01-01
      • 2020-07-17
      相关资源
      最近更新 更多