应用程序被杀死时,SharedPreferences被删除

3
我有一个服务,可以接收通知(使用Google Cloud Messaging),并通知用户。在该服务中,我还使用SharedPreferences存储由Cloud Messaging发送的消息。我将这些消息收集到一个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());

2
在调用editor.putStringSet("SETMESSAGES", setMessages);之前,先调用editor.clear(); - Ramesh
@MeTechnical 这段代码不是在静态方法中,它无论是在onHandleIntent()方法中还是在被onHandleIntent()调用的非静态方法中(其签名为private void sendNotification(Bundle extras))。 - Kritias
@Kritias 在实际中,将消息或任何频繁变动的数据存储在SP中并不理想,也不建议这样做。相反,您可以使用SQLite或类似的数据库(如Realm)来实现。SP主要用于存储偶尔变化的少量信息,而且SP的写入是一项较为繁重的操作。 - Hanu
请参考https://dev59.com/0Gkw5IYBdhLWcg3wkLX2#31598304,以获取此问题的真正解决方案。 - Sam
显示剩余2条评论
3个回答

3
在设置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();

5
调用 editor.clear(); 将清除所有的首选项。你不想这样,对吗? - Shadab Ansari
似乎对新值起作用,但是添加editor.clear后,会清除prefs中保存的任何其他值。 - SKG
正确的解决方案是先移除键并放置字符串。 - SKG

0

当您更新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()


0

多亏了Ramesh的评论,我解决了这个问题。在editor.putStringSet("SETMESSAGES", setMessages);之前添加editor.clear();就修复了它。然而,我对为什么之前不起作用一无所知。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接