【问题标题】:Default Shared Preferences give me wrong values in Service默认共享首选项在服务中给了我错误的值
【发布时间】:2014-05-15 09:41:33
【问题描述】:

我有一个 PreferenceFragment,我在 XML 中定义了一个 CheckBoxPreference。我需要在服务中检查这个值,但它总是给我旧值。当我重新启动应用程序时,我注意到该值已正确更改。

我的偏好片段:

public class OptionsFragment extends PreferenceFragment 
{

    public static final String WIFI_ONLY = "wifi";

    private SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(MyApplication.getInstance());

    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.config);
    }

 }

我的 config.xml :

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >

    <CheckBoxPreference
        android:defaultValue="true"
        android:key="wifi"
        android:summary="Check if you want to use wifi only"
        android:title="Use Wifi only" />

</PreferenceScreen>

我的服务:

SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(MyApplication.getInstance());        
Log.d(TAG, "isWifiOnly : "+settings.getBoolean(OptionsFragment.WIFI_ONLY, true));

无论我是否更改日志,日志总是返回相同的值,除非我重新启动应用程序。此外,在我的 MainActivity 中,我在 OnCreate() 中有该行:

PreferenceManager.setDefaultValues(getApplicationContext(), R.xml.config, false);

如果需要,它会使用默认值创建配置文件。

我做错了什么,问题是什么?

【问题讨论】:

  • 我觉得我也有这个问题,我用Context.MODE_MULTI_PROCESS解决了。 This question 是我之前发现的。编辑:评论太快,没有阅读整个问题;在这种情况下,也许PreferenceManager.setSharedPreferencesMode() 可以解决问题。
  • setSharedPreferencesMode() 不是静态的,我必须在我的偏好片段中添加这一行,就在 addPreferencesFromResource() 之后: getPreferenceManager().setSharedPreferencesMode(Context.MODE_MULTI_PROCESS);但不幸的是它仍然不起作用
  • 抱歉,没有仔细阅读文档……而且,那个时候,我在Service 中使用了本地SharedPreferences 并且它有效。如果这没有帮助,请道歉。
  • 它有帮助 :) 您能否描述一下您是如何在您的服务中编写本地 SharedPreferences 的?您是否将 DefaultSharedPreences 与 ApplicationContext 一起使用?还是您使用与名称和模式链接的简单 SharedPreferences ?
  • 我使用了与 Activity 链接的 SharedPreferences。由于我现在无法访问代码,因此无法描述它。 (有点忘了,但我相信我只是像普通的 SharedPreferences 一样使用它)。有时间我会回复你的。

标签: android sharedpreferences


【解决方案1】:

感谢此链接Managing SharedPreferences in both PreferenceActivity and Service within same app 并感谢 Andrew T.,我找到了解决方案:

问题是多进程模式。如果你有一个在清单中用 android:process="" 声明的服务(这是我的情况),那么有必要设置一个多进程模式。

这就是我所做的:

在 PreferenceFragment 中:

public static final String CONFIG_NAME = "pref";

...

@Override
public void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);


    getPreferenceManager().setSharedPreferencesName(CONFIG_NAME);
    getPreferenceManager().setSharedPreferencesMode(Context.MODE_MULTI_PROCESS);

    addPreferencesFromResource(R.xml.config);

    ...
}

我的服务:

SharedPreferences settings = MyApplication.getInstance().getSharedPreferences(OptionsFragment.CONFIG_NAME, Context.MODE_MULTI_PROCESS);

我以这种方式在 MainActivity 中设置默认值:

PreferenceManager.setDefaultValues(getApplicationContext(), OptionsFragment.CONFIG_NAME, Context.MODE_MULTI_PROCESS, R.xml.config, false);

现在它工作正常。希望它会有所帮助!

再次感谢安德鲁 T。

【讨论】:

    【解决方案2】:

    最近几天我也遇到了同样的问题...

    我有一个带有我的布局和键的preference.xml,并在侦听更改时将其扩展为PreferenceFragment,从而将我的应用程序的任何更改通知服务。 关键是设置SharedPreference访问权限的模式:

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);
        getPreferenceManager().setSharedPreferencesMode(Context.MODE_MULTI_PROCESS);
    }
    

    Context.MODE_MULTI_PROCESS 标志使 commits() 适用于所有访问进程,因此即使我的服务也可以直接访问刚刚更改的值。

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)
    {
        if(SettingsManager.setupIsValid(getActivity())){
            Intent startServiceIntent = new Intent(getActivity(), IntentService.class);
            startServiceIntent.setAction("PREFERENCES_CHANGED");
            getActivity().startService(startServiceIntent);
        } else {
            Toast.makeText(getActivity(), getString(R.string.settings_incomplete), Toast.LENGTH_SHORT).show();
        }
    }
    

    这将首先检查魔术,并且只要设置有效,就会通知服务更改。

    这允许使用多个进程并始终跨所有进程使用当前首选项值。

    P.S.:直接访问然后看起来像这样

    SharedPreferences prefs = context.getSharedPreferences(context.getPackageName() + "_preferences", Context.MODE_MULTI_PROCESS);
    

    【讨论】:

      猜你喜欢
      • 2013-07-19
      • 2013-06-19
      • 1970-01-01
      • 1970-01-01
      • 2019-05-11
      • 1970-01-01
      • 2018-06-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多