【问题标题】:SharedPreferences in BroadcastReceiver seems to not update?BroadcastReceiver 中的 SharedPreferences 似乎没有更新?
【发布时间】:2012-04-23 08:20:11
【问题描述】:

我有一个更新 SharedPreferences 中的字符串的活动。

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

然后我启动一个服务:

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

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

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", ""));
}

【问题讨论】:

  • 如何更改用户名?确保在将其放入共享首选项之前保存正确的用户名
  • 可悲的是,我只是在做典型的 putString 然后是 editor.commit()。有趣的是,如果我执行 getString,它会一直拉取更新的用户名,直到最后一步 onReceive..
  • 我也遇到了同样的问题。你找到解决这个问题的方法了吗?

标签: android broadcastreceiver sharedpreferences alarmmanager


【解决方案1】:

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

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

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

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

【讨论】:

  • 谢谢你!我最终通过使用 ActivityManager.killBackgroundProcess 在这种情况下停止服务来解决它。当它再次启动时,它会正确获取新数据。缺点是它需要新的用户权限,但它可以工作。
  • 我要标记你的正确,因为它在技术上看起来是正确的!
  • 请问:您是如何找到这样的解决方案的?你用共享首选项解决了我 3 天的问题。
  • 感谢阿米尔的解决方案。
  • 非常感谢@Amir,因为我也很困惑为什么它不工作但现在很好谢谢
【解决方案2】:

不幸的是,Amir Naor 的解决方案在我的 Android 7 应用程序中不起作用。似乎每个接收者总是在一个新的进程中开始。

API

所以如果你的应用 Context.MODE_MULTI_PROCESS:

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

API >= 23

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


github上有一个非常不错的库:Tray - a SharedPreferences replacement for Android。这个库是一个 ContentProvider 包装器,具有一些其他有用的特性。试试看吧。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-11
    • 2021-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多