14

编辑: 下面描述的问题是由于一个非常特殊的设备问题而不是由任何与编码相关的问题引起的。

我有一个preferenceActivity,其中有很多checkBoxPreferences。checkBoxPreference 假设保存默认的共享首选项文件,然后在我打开应用程序时再次调用以更新 UI。

这不会像预期的那样发生。如果我关闭应用程序并重新打开它,我的值将保持原样,但如果我使用任务管理器结束应用程序或者如果我重启手机(当应用程序未运行时),则调用 defaultValues再次。

所以,我在 onResume() 中创建了一个 SharedPreference 来测试它。

SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

然后我检查该共享首选项中是否有密钥。

pref.contains("myCheckBoxPreference");

当我关闭并重新打开它时,它返回true。如果我关闭任务管理器或关闭和打开手机电源,则返回错误。

所以,我尝试手动设置 SharedPreference

SharedPreferences.Editor editor = pref.edit();
editor.putBoolean("myCheckBoxPreference", myCheckBoxPreference.isChecked());
editor.commit();

然后当 checkboxpreference 值改变时我调用它。我还尝试在 onStop 和 onPause 中调用它。尽管如此,如果我关闭应用程序并重新打开它,pref.contains 返回 true,但如果我关闭并重新打开手机,它返回 false。

所以我然后尝试使用 SharedPreferences 文件。

在类声明中:

public static final String PREFS = "prefs";

在 onResume() 中:

SharedPreferences pref = this.getSharedPreferences(PREFS, 0);

同样的行为,如果我只是关闭应用程序并重新打开它,pref.contains 仍然返回 true,但如果我关闭并重新打开手机,它会返回 false。

然后我尝试将 myCheckBoxPreference 的键值更改为与 CheckBoxPreference 的 xml 键不匹配的值,它仍然具有相同的效果。

然后我把手机里的应用程序卸载了,然后关机再开机,再重新安装,还是一样的效果。

4

7 回答 7

7

我刚刚解决了,我很确定。我没有代码错误,我的应用程序也没有任何问题(无论如何我不相信。)

我创建了一个名为“testproj”的新项目,然后我从我的设置 PreferenceActivity 中复制了所有代码,将其粘贴到 TestprojActivity 中,然后我从它所依赖的 xml 中复制了代码,然后将其粘贴到了 TestProj 的 main.xml 中。

然后我在三星 Captivate 上安装了 TestProj,更改了设置,通过 RAM 管理(我拥有的自定义 ROM 的功能)清除了 ram,然后设置卡住了。然后我重启手机,设置仍然存在,就像我配置它们一样。

当我使用以下方法手动设置它们时,它们都保持不变:

PreferenceManager.getDefaultSharedPreferences();

并且无需手动将它们保存到 SharedPreferences。

因为它不是我的手机,所以我还没有尝试过,但我认为恢复出厂数据会完全 修复

我浪费了很多时间试图弄清楚这一点,我希望它可以帮助别人。:)

于 2011-07-01T23:19:30.000 回答
6

我在三星 Galaxy S 上遇到了可能类似的问题,其中偏好 XML 文件的权限以某种方式更改/损坏。

日志显示某些主机进程无法读取文件,导致所有设置重置为默认值。我不记得确切的错误消息,但它与“/path/to/preferences/file.xml 的权限被拒绝”类似。

我的解决方案是通过设置、应用程序、管理应用程序、MyApp、删除数据删除应用程序数据。这将删除与应用程序关联的首选项文件,问题立即消失。

我认为这是一个孤立的事件,因为我没有在各种 Android 设备(包括 Galaxy S II)上再次遇到它。

于 2011-07-01T23:26:34.200 回答
3

在客户的主要测试设备上,我遇到了同样的问题。使用的设备是具有 SDK 级别 8 (2.2.1) 的三星 Galaxy S。

奇怪的行为是要么SharedPreferences没有保存,要么在恢复出厂设置后,它们太持久了,也就是说,在重新安装应用程序后它们没有被删除。

由于目前2.2.x 的分布,以及三星 Galaxy S 设备的销售数量为数百万,因此发生此问题的概率很大

因此,实施用于保存首选项的变通方法可以被认为是至关重要的。

为了收集详细的特征以尖锐的方式隔离此解决方法,是否也面临该问题的每个人都可以在此处提供相应的内核版本System.getProperty("os.version")?

我在想这样的事情:

// !! I know that 2.6.32.9 is not yet correct. This would be a false positive !!
if ((System.getProperty("os.version").startsWith("2.6.32.9"))
    && (android.os.Build.DEVICE.contains("GT-I9000")))
    useInternalStorage();
else
    useSharedPreferences();

一旦准备好并且有人感兴趣,我也可以在这里发布真正的代码。


编辑:一些附加信息:

面临该问题的设备:

    物业 | 价值观
    ---------------------------------+---------------- --------------------
    构建.设备 | “GT-I9000T”
    Build.VERSION.INCREMENTAL | “UBJP9”
    Build.VERSION.RELEASE | “2.2.1”
    Build.VERSION.SDK | 8
    System.getProperty("os.version") | “2.6.32.9”
    

未面临该问题的类似设备:

    物业 | 价值观
    ---------------------------------+---------------- --------------------
    构建.设备 | “GT-I9000”
    Build.VERSION.INCREMENTAL | “AOJP4”
    Build.VERSION.RELEASE | “2.2”
    Build.VERSION.SDK | 8
    System.getProperty("os.version") | “2.6.32.9”
    

于 2011-09-26T12:16:53.560 回答
3

在设置值之前尝试清除编辑器。我有同样的问题,它对我有用。例子:

Editor e = PreferenceManager.getDefaultSharedPreferences(getParent()).edit();
e.clear();
e.putStringSet(key, value);
于 2013-09-22T21:35:22.203 回答
0

可以通过使用 sharedUserId 来解决权限问题,对于您的任何签名应用程序都应该是相同的。

http://developer.android.com/reference/android/R.attr.html#sharedUserId

于 2011-11-09T18:01:19.530 回答
0

我也有保存然后检索数据的问题。我将保存和加载代码放在一个扩展应用程序的类中,因为我想要一个数据实例。我可以看到字符串被保存,LogCat 中没有错误,但是当我尝试加载它时,再次没有错误,我的字符串为空。我从来没有检查过数据是否真的进入了文件,所以我不知道保存或加载是否失败或两者兼而有之。

我的代码或多或少如下:(comboToSave 只是 Gson 从一个简单的数据类生成的字符串)

在一种保存方法中:

  SharedPreferences sharedPref = activity.getPreferences(Context.MODE_PRIVATE); 
  SharedPreferences.Editor editor = sharedPref.edit();
  editor.putString(getString(R.string.prefCombos), comboToSave); 
  editor.commit();

在另一种加载方法中:

  SharedPreferences sharedPref = activity.getPreferences(Context.MODE_PRIVATE);
  String loadedComboText = sharedPref.getString(getString(R.string.prefCombos), "");

经过大量的头疼并且不知道该怎么做之后,我更改了从中检索 sharedPref 值的代码

SharedPreferences sharedPref = activity.getPreferences(Context.MODE_PRIVATE);

SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

这里还有一些关于两者之间的区别(尽管在我的情况下看起来完全一样)

我的 Galaxy S3 上的结果仍然是一样的。但是,在包括 VD(虚拟设备)在内的其他设备上测试这两个版本都有效。

在代码的第一个版本中,我从调用活动中传递了活动;从从用户那里收集最后一点数据的活动中保存,并从我的主要活动中加载,以便在启动应用程序时准备好它。

我昨晚玩了卸载应用程序并重新安装,关闭设备然后再次打开,但无济于事。

我现在已经将保存和加载方法从应用程序类移动到我完成输入的活动,即加载和保存代码现在都在同一个活动中。我已经用两种代码变体对此进行了测试,它们都可以工作。我拿回我保存的东西。然后我将所有代码移回 Application 类并且它可以工作;这让我相信,通过所有的安装/卸载,我以某种方式设法让它工作。 要点是:代码是正确的 - 如果它不起作用,设备和/或设置可能是罪魁祸首

于 2013-07-16T11:35:53.677 回答
0

我也遇到了同样的问题,苦恼了一阵子,终于找到了解决办法,就是这么简单,直接传activity的引用就行了,不使用任何通用上下文

public SessionManagment(Activity mContextActivity){
//  this.contextActivity = mContext;
    sharedPrefSession =  mContextActivity.getSharedPreferences(
            Constants.SHARED_PREFERANCES_LIGHT_TIGER_SESSION_FILE_NAME, 
            Context.MODE_PRIVATE);

}//enden constructor 

上面的代码是我为会话管理编写的类的构造函数,当我在 AsyncTask 的主 ActivityFramgment 的代码中调用它时,我这样称呼它

SessionManagment sessionManagment = new SessionManagment(referanct2thisActivity);

其中referanct2thisActivity在这样的片段活动的“onCreate”函数中定义

referanct2thisActivity = this;

希望将来会帮助其他人

于 2013-08-22T07:51:41.910 回答