BroadcastReceiver中的SharedPreferences似乎没有更新?

时间:2012-04-11 02:13:49

标签: android broadcastreceiver sharedpreferences alarmmanager

我有一个Activity,用于更新SharedPreferences中的字符串。

SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = settings.edit();
editor.putString("username", username);
editor.commit();

然后我开始服务:

startService(new Intent(this, MyService.class));

该服务创建一个对Alarm的引用,该引用扩展了BroadcastReceiver:

Alarm alarm = null;
public void onCreate() {
    alarm = new Alarm();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    alarm.SetAlarm(this);
}

在SetAlarm中我做了所有基本的设置工作(此时,“用户名”仍然正确..我查了一下):

public void SetAlarm(Context context) {
    AlarmManager am=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
    PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
    am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), 1000 * 60 * interval, pi);
}

然后我停止服务,然后再次启动它(使用SetAlarm)。

public void CancelAlarm(Context context) {
   Intent intent = new Intent(context, Alarm.class);
   PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
   AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
   alarmManager.cancel(sender);
}

问题出在onReceive ..第一次“用户名”字段是正确的。第二次,如果在服务停止和启动之间更新用户名,则返回第一个值。该值似乎没有更新......

public void onReceive(Context context, Intent intent) {   
    SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
    Log.e("hi", settings.getString("username", ""));
}

2 个答案:

答案 0 :(得分:62)

我遇到了同样的问题,在经过几个小时的努力解决之后,我终于找到了导致它的问题。在你的AndroidManifest中你可能有类似的东西:

<receiver android:name="AlarmReceiver" android:process=":remote" />

最后一个属性(进程:远程)导致接收器在调用时在不同的/新进程上运行。但不同进程之间不支持SharedPreferences。

所以我做的是从清单中删除最后一个属性。这意味着代码现在将在主线程上运行 - 但如果您只有几行来显示通知,那么这应该不是问题。另一种方法是调用服务来运行长操作。

答案 1 :(得分:1)

不幸的是,Amir Naor的解决方案在我的Android 7 App中无效。似乎每个接收器总是在一个新的过程中开始。

API&lt; 23

因此,如果你的应用程序&lt; API级别23,您可以使用标记Context.MODE_MULTI_PROCESS

context.getSharedPreferences("mypreferences", Context.MODE_PRIVATE | Context.MODE_MULTI_PROCESS);

API&gt; = 23

真是一个惊喜。由于API级别23是标记Context.MODE_MULTI_PROCESS deprecated,我们应该使用ContentProvider来共享进程之间的属性。

github上有一个非常好的库:Tray - a SharedPreferences replacement for Android。该库是ContentProvider包装器,具有一些其他有用的功能。试一试。