请教各位高手有关SharedPreferences跨应用读取数据的问题

gcsdn2000 2012-03-22 01:26:24
我写了两个不同的应用程序,然后其中一个程序A利用SharedPreferences来读取另一个程序B写入的数据。现在出现了一个奇怪的问题:程序A第一次启动后可以读取到程序B写入的数据,但是当我利用Android模拟器上的返回键退出程序A,然后启动程序B对数据进行修改并写入XML文件后,再次启动程序A,按道理程序A读取到的数据应该是修改后的数据,但是结果仍然是程序A第一次启动时读取到的数据,而不是修改后的数据,无论我在程序B里对数据进行多少次修改,程序A都只能读取到第一次的数据。

想问下各位高手,为什么会出现这种情况?

相关程序我打包上传到CSDN上了,下载地址如下:http://download.csdn.net/detail/gcsdn2000/4161520

共有两个程序,其中1.2SimplePreference是用来写入的,1.2SharePreference是用来读取的。

----------------------------------------------

另外我在查找原因的时候,发现用模拟器上的返回键退出程序时,程序虽然已经执行了onDestroy(),但是其实还是在模拟器后台缓存里存在着,这个可以通过“应用程序->正在运行->显示缓存进程”里看到。
如果这时我在“显示缓存进程”里强制停止程序A,然后再次回去执行程序A,程序A就可以读取到更新后的数据了,但是仍然只能读取到第一次的数据,除非每次都强制停止程序。当然通过System.exit(0);也可以达到同样的效果。

现在问题是:既然程序B已经修改了数据(这个我通过File Explorer提取XML文件查看后数据的确已经修改了),按道理无论程序A是否完全退出,每次执行应该都读到更新后的数据,那为什么还是显示第一次读取到的数据呢?
程序A肯定执行了完整的生命周期,从启动执行到通过模拟器上的返回键退出然后再执行,只是还驻留在缓存里,这对数据的更新会有影响吗?
主要的读取数据代码如下:
try {
c = this.createPackageContext(PREFERENCE_PACKAGE, Context.CONTEXT_IGNORE_SECURITY);

} catch (NameNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

SharedPreferences sharedPreferences = c.getSharedPreferences(PREFERENCE_NAME, MODE);

String name = sharedPreferences.getString("Name","Tom");
int age = sharedPreferences.getInt("Age", 20);
float height = sharedPreferences.getFloat("Height",1.81f);

String msg = "";
msg += "姓名:" + name + "\n";
msg += "年龄:" + String.valueOf(age) + "\n";
msg += "身高:" + String.valueOf(height) + "\n";

labelView.setText(msg);

按理说每次执行都应该读取到最新的数据,但是测试结果,这些变量的值都是第一次读到的值,不会有变化,除非从缓存中完全退出,然后再次启动才会读到最新的值。即使缓存里保留了老的值,但是当执行上述代码是应该读到新的值,然后把老的值覆盖掉,这样就应该显示新的值,难道Android和其他系统的不一样?

有高手能说下问什么会出现上面的那种情况?我自己实在无法找到合理的解释。

先谢谢了!
...全文
1632 44 打赏 收藏 转发到动态 举报
写回复
用AI写文章
44 条回复
切换为时间正序
请发表友善的回复…
发表回复
sdhgood 2014-05-06
  • 打赏
  • 举报
回复
我在A程序里设置了 MODE_WORLD_READABLE, B程序里设置了 Context.MODE_WORLD_READABLE|Context.MODE_MULTI_PROCESS 好使了
南瓜鱼 2013-12-31
  • 打赏
  • 举报
回复
我也遇到了这个问题。由于需求是其他应用程序只能读取,因 此我的做法是在A和B应用中设置mode为: MODE_WORLD_READABLE|MODE_MULTI_PROCESS。 若只有B设置为 MODE_WORLD_READABLE|MODE_MULTI_PROCESS, 而A设置为MODE_WORLD_READABLE也是不行的。 (PS:其实这里我也有点不解,为什么A应用也要设置MODE_MULTI_PROCESS) 关于MODE_MULTI_PROCESS: 在Android 2.3及以前,MODE_MULTI_PROCESS这个标志位都是默认开启的,允许多个进程访问同一个SharedPrecferences对象。而以后的Android版本,必须通过明确的将MODE_MULTI_PROCESS这个值传递给mode参数,才能开启多进程访问。
RichardHuang87 2013-03-30
  • 打赏
  • 举报
回复
我也遇到了,但是最好把代码
c = this.createPackageContext(PREFERENCE_PACKAGE, Context.CONTEXT_IGNORE_SECURITY);

} catch (NameNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

SharedPreferences sharedPreferences = c.getSharedPreferences(PREFERENCE_NAME, MODE);
    
String name = sharedPreferences.getString("Name","Tom");
int age = sharedPreferences.getInt("Age", 20);
float height = sharedPreferences.getFloat("Height",1.81f);
写在一个函数里面,因为同楼上说的,要获取同一个类。因为重写onclick这些函数里面往往是不同类。所以获取不到。我遇到的就这种情况
顾小林 2013-03-02
  • 打赏
  • 举报
回复
首先 每次B修改完 把那个xml 推出来看看是否 数据真的改变过 android 如何读取其他应用的SharedPreferences 大家可能没有留意 getPreferences()这个方法调用的时候需要上下文环境,也就是调用的时候隐式的省略了this this.getPreferences(); 而在应用中这个this 可以理解为包名环境。 所以如何使外部应用分享该应用的数据打架可以晓得了。 以下贴出代码 public class SharedataActivity extends Activity { SharedPreferences mSharedPreferences; Context mContext; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); try {//org.example.test数据存放的包名 mContext = createPackageContext("org.example.test", Context.CONTEXT_IGNORE_SECURITY); } catch (NameNotFoundException e) { Toast.makeText(getApplicationContext(), "shibai", Toast.LENGTH_SHORT).show(); e.printStackTrace(); } mSharedPreferences = mContext.getSharedPreferences("shenwenjian", MODE_WORLD_READABLE);//shenwenjian 为 sharepreferences的名字 Toast.makeText(this, mSharedPreferences.getString("name", "null"), Toast.LENGTH_SHORT).show(); } } 注意你创建这个SharedPreferences 时候的权限
wzxxzw5191 2013-03-01
  • 打赏
  • 举报
回复
MODE_MULTI_PROCESS 这个是从什么地方来的?我看到的只有 MODE_PRIVATE MODE_WORLD_READABLE MODE_WORLD_WRITEABLE 这三个啊~~这个问题在 三星和中兴的手机上都试过,都会出现读的是缓存的旧数据,期待高手解答啊~~
王大狼山 2013-03-01
  • 打赏
  • 举报
回复
可能是另外一个activity 没有完全退出 可以尝试关闭再读取
顾小林 2013-01-07
  • 打赏
  • 举报
回复
你可以在B程序对数据修改以后拉出来那个XML 看存储信息,很容易看懂的,然后就知道修改是否有效
viptmd 2013-01-06
  • 打赏
  • 举报
回复
引用 31 楼 gcsdn2000 的回复:
可能平板和手机不一样?
LZ 我解决了在B那边用MODE_MULTI_PROCESS 不要用MODE_WORLD_READABLE
viptmd 2013-01-06
  • 打赏
  • 举报
回复
我也遇到和LZ一样的问题 , 不知道LZ解决的没有,不能理解,为什么不能更新
顾小林 2012-12-13
  • 打赏
  • 举报
回复
可以跨应用读取数据 context 的时候获取到 你要读取的那个包名就ok 就是那个类似于 android.xxx.xxx的那个东西 不过前提是你的sharedpreference 设置的可以共享
hxm2818 2012-12-13
  • 打赏
  • 举报
回复
非常好~!可以了
chengAdam 2012-11-08
  • 打赏
  • 举报
回复
在A中MODE+Context.MODE_MULTI_PROCESS,试一下
gcsdn2000 2012-09-30
  • 打赏
  • 举报
回复
可能平板和手机不一样?
gcsdn2000 2012-09-30
  • 打赏
  • 举报
回复
没有在平板上运行过,只在模拟器上运行过!
feisty2012 2012-09-05
  • 打赏
  • 举报
回复
求解呀,我在4.0平板上面也遇到了。
feisty2012 2012-09-05
  • 打赏
  • 举报
回复
我也遇到了,在4.0平板上面,求解???
GuoQun06 2012-08-31
  • 打赏
  • 举报
回复
我遇到了同样的问题。等待你的解答。。。
canglongyt 2012-07-04
  • 打赏
  • 举报
回复
请问楼主问题怎么解决的? 我也出现这个问题了, 单板不是模拟器, 4.0系统, 读的就是第一次的缓存
gcsdn2000 2012-04-20
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 的回复:]
Lz程序,真机上运行没有问题,估计是模拟器的问题缓存没刷新吧
[/Quote]
----------------------------
谢谢!看来应该就是这个问题了。


[Quote=引用 24 楼 的回复:]
再次启动程序A,按道理程序A读取到的数据应该是修改后的数据
-----------------------------------------------------
lz 可以看看你的Oncreate方法有没有再次执行啊
[/Quote]
-----------------------
看了,Oncreate方法再次执行了。
应该是模拟器的问题。
life02 2012-03-31
  • 打赏
  • 举报
回复
再次启动程序A,按道理程序A读取到的数据应该是修改后的数据
-----------------------------------------------------
lz 可以看看你的Oncreate方法有没有再次执行啊
加载更多回复(21)

80,492

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧