当前位置:编程学习 > wap >>

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

    我写了两个不同的应用程序,然后其中一个程序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和其他系统的不一样?

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

    先谢谢了! --------------------编程问答-------------------- 我记得SharedPreferences 不能跨应用读取数据吧,使用contentprovider它吧。 --------------------编程问答-------------------- 在 Back 按钮的时候调用 finish() 试一试 --------------------编程问答-------------------- SharedPreferences是一种轻量级的数据保存方式 采用键值对NVP保存在文件系统中

可用于保存数据以及实现不同应用程序间的数据共享

支持3种访问模式

●MODE_PRIVATE 私有

●MODE_WORLD_READABLE 全局读

●MODE_WORLD_WRITEABLE 全局写

我又特意查了一下  确实是的  是不是 模式没有写对 --------------------编程问答--------------------
引用 1 楼 ihrthk 的回复:
我记得SharedPreferences 不能跨应用读取数据吧,使用contentprovider它吧。

-----------------------
可以跨引用读取的,要不然第一次应该读不出任何数据,现在问题是程序B更新数据后,程序A读不到更新后的数据。 --------------------编程问答--------------------
引用 2 楼 lazy_2010 的回复:
在 Back 按钮的时候调用 finish() 试一试

试过了,没有用,其实用了finish()程序依然驻留在缓存里
只有用System.exit(0);才能完全退出缓存。 --------------------编程问答--------------------
引用 3 楼 j2me01 的回复:
SharedPreferences是一种轻量级的数据保存方式 采用键值对NVP保存在文件系统中

可用于保存数据以及实现不同应用程序间的数据共享

支持3种访问模式

●MODE_PRIVATE 私有

●MODE_WORLD_READABLE 全局读

●MODE_WORLD_WRITEABLE 全局写

我又特意查了一下 确实是的 是不是 模式没有写对

模式是全局读+全局写,两个程序都是这个模式,肯定不是模式的问题
如果是模式的问题,应该第一次也读不到任何数据。 --------------------编程问答-------------------- 帮顶一个,望楼主早日解决 --------------------编程问答--------------------
引用 7 楼 fire_fire_fire 的回复:
帮顶一个,望楼主早日解决

谢谢! --------------------编程问答-------------------- public static int MODE = Context.MODE_WORLD_READABLE|Context.MODE_WORLD_WRITEABLE;
我这里实验可以 --------------------编程问答--------------------
引用 9 楼 leer168 的回复:
public static int MODE = Context.MODE_WORLD_READABLE|Context.MODE_WORLD_WRITEABLE;
我这里实验可以

不知道这里说的可以是指什么可以,这个模式没什么问题吧,我用的是如下:
public static int MODE = Context.MODE_WORLD_READABLE + Context.MODE_WORLD_WRITEABLE; --------------------编程问答-------------------- 我下载你的程序试过了,,没有问题,
我再想是不是你模拟器有问题啊

你可以试试把工程1.2sharepreferenceg中的SharePreferenceActivity类中oncreate()方法中的代码:
Context c = null;
        labelView = (TextView)findViewById(R.id.label);  
        
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);   

Toast.makeText(this, name, Toast.LENGTH_SHORT).show();

放到onResume()方法中

因为你有时候点击back再次进入程度时oncearte()方法可能没有调用,因为你的程序只是切换到了后台 --------------------编程问答-------------------- 我也以为sharedpreference不能跨应用读取的 --------------------编程问答-------------------- 顶j2me01的回复! --------------------编程问答-------------------- 我咋也看到是这么说的啊?我没有花眼吧
引用 12 楼 jsplove 的回复:
我也以为sharedpreference不能跨应用读取的
--------------------编程问答-------------------- 。。。。只是写demo的时候玩过一下,真实开发估计没什么人用这玩意搞

楼主说的是脏读。。。这个可能是google实现的问题,但同一个应用中不会出现脏读的现象 --------------------编程问答-------------------- 还不如写文件呢 --------------------编程问答--------------------
引用 11 楼 zhouyongyang621 的回复:
我下载你的程序试过了,,没有问题,
我再想是不是你模拟器有问题啊

你可以试试把工程1.2sharepreferenceg中的SharePreferenceActivity类中oncreate()方法中的代码:
Context c = null;
  labelView = (TextView)findViewById(R.id.label);  
   
try {
c = th……

谢谢!这个我试一下! --------------------编程问答--------------------
引用 12 楼 jsplove 的回复:
我也以为sharedpreference不能跨应用读取的

可以的 --------------------编程问答--------------------
引用 14 楼 ritazuozuo 的回复:
我咋也看到是这么说的啊?我没有花眼吧

引用 12 楼 jsplove 的回复:
我也以为sharedpreference不能跨应用读取的

可以的 --------------------编程问答-------------------- --------------------编程问答--------------------
引用 11 楼 zhouyongyang621 的回复:
我下载你的程序试过了,,没有问题,
我再想是不是你模拟器有问题啊

你可以试试把工程1.2sharepreferenceg中的SharePreferenceActivity类中oncreate()方法中的代码:
Context c = null;
  labelView = (TextView)findViewById(R.id.label);  
   
try {
c = th……

试了一下,还是不行

不过你说的模拟器的问题是指什么? --------------------编程问答-------------------- --------------------编程问答-------------------- Lz程序,真机上运行没有问题,估计是模拟器的问题缓存没刷新吧 --------------------编程问答-------------------- 再次启动程序A,按道理程序A读取到的数据应该是修改后的数据
-----------------------------------------------------
lz 可以看看你的Oncreate方法有没有再次执行啊 --------------------编程问答--------------------
引用 23 楼  的回复:
Lz程序,真机上运行没有问题,估计是模拟器的问题缓存没刷新吧

----------------------------
谢谢!看来应该就是这个问题了。


引用 24 楼  的回复:
再次启动程序A,按道理程序A读取到的数据应该是修改后的数据
-----------------------------------------------------
lz 可以看看你的Oncreate方法有没有再次执行啊

-----------------------
看了,Oncreate方法再次执行了。
应该是模拟器的问题。 --------------------编程问答-------------------- 请问楼主问题怎么解决的? 我也出现这个问题了, 单板不是模拟器, 4.0系统, 读的就是第一次的缓存 --------------------编程问答-------------------- 我遇到了同样的问题。等待你的解答。。。 --------------------编程问答--------------------  我也遇到了,在4.0平板上面,求解??? --------------------编程问答-------------------- 求解呀,我在4.0平板上面也遇到了。 --------------------编程问答-------------------- 没有在平板上运行过,只在模拟器上运行过! --------------------编程问答-------------------- 可能平板和手机不一样? --------------------编程问答-------------------- 在A中MODE+Context.MODE_MULTI_PROCESS,试一下 --------------------编程问答-------------------- 非常好~!可以了 --------------------编程问答-------------------- 除 --------------------编程问答-------------------- 可以跨应用读取数据  context 的时候获取到 你要读取的那个包名就ok 就是那个类似于 android.xxx.xxx的那个东西 不过前提是你的sharedpreference 设置的可以共享 --------------------编程问答-------------------- 我也遇到和LZ一样的问题 , 不知道LZ解决的没有,不能理解,为什么不能更新 --------------------编程问答--------------------
引用 31 楼 gcsdn2000 的回复:
可能平板和手机不一样?

LZ 我解决了在B那边用MODE_MULTI_PROCESS 不要用MODE_WORLD_READABLE --------------------编程问答-------------------- 你可以在B程序对数据修改以后拉出来那个XML 看存储信息,很容易看懂的,然后就知道修改是否有效 --------------------编程问答-------------------- 可能是另外一个activity 没有完全退出  可以尝试关闭再读取 --------------------编程问答-------------------- MODE_MULTI_PROCESS 这个是从什么地方来的?我看到的只有 MODE_PRIVATE MODE_WORLD_READABLE MODE_WORLD_WRITEABLE 这三个啊~~这个问题在 三星和中兴的手机上都试过,都会出现读的是缓存的旧数据,期待高手解答啊~~

--------------------编程问答-------------------- 首先 每次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 时候的权限 --------------------编程问答-------------------- 我也遇到了,但是最好把代码
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这些函数里面往往是不同类。所以获取不到。我遇到的就这种情况
补充:移动开发 ,  Android
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,