mar*_*mor 29 android multiprocessing sharedpreferences
我SyncAdapter在主应用程序进程中独立运行自己的进程.
我正在使用一个静态包装类SharedPreferences,它在进程加载(应用程序onCreate)上创建一个静态对象,如下所示:
myPrefs = context.getSharedPreferences(MY_FILE_NAME, Context.MODE_MULTI_PROCESS | Context.MODE_PRIVATE);
Run Code Online (Sandbox Code Playgroud)
包装器有get和set方法,如下所示:
public static String getSomeString() {
return myPrefs.getString(SOME_KEY, null);
}
public static void setSomeString(String str) {
myPrefs.edit().putString(SOME_KEY, str).commit();
}
Run Code Online (Sandbox Code Playgroud)
两者SyncAdapter和app都使用这个包装类来编辑和从prefs获取,这有时会工作,但很多时候我看到SyncAdapter在访问prefs时获取旧/缺少的prefs,而主应用程序正确地看到了最近的更改.
根据文档,我认为MODE_MULTI_PROCESS标志应该像我期望的那样工作,允许两个进程看到最新的更改,但它不起作用.
更新:
根据Per x90的建议,我试图避免使用静态SharedPreferences对象,而是调用getSharedPreferences每个get/set方法.这导致了一个新问题,即prefs文件在多进程同时访问时被删除(!!!).即我在logcat中看到:
(process 1): getName => "Name"
(process 2): getName => null
(process 1): getName => null
Run Code Online (Sandbox Code Playgroud)
从那时起,保存在SharedPreferences对象上的所有prefs 都被删除了.
这可能是我在日志中看到的另一个警告的结果:
W/FileUtils(21552): Failed to chmod(/data/data/com.my_company/shared_prefs/prefs_filename.xml): libcore.io.ErrnoException: chmod failed: ENOENT (No such file or directory)
Run Code Online (Sandbox Code Playgroud)
PS这不是一个确定性的问题,我在发生崩溃后看到了上面的日志,但是无法在同一台设备上重新创建,直到现在它似乎没有在其他设备上发生.
另一个更新:
我已经提交了一份关于此的错误报告,在编写了一个小测试方法以确认这确实是一个Android问题之后,请点击https://code.google.com/p/android/issues/detail?id=66625
小智 26
我快速浏览了一下Google的代码,显然Context.MODE_MULTI_PROCESS这不是确保SharedPreferences流程安全的实际方法.
SharedPreferences本身不是过程安全的.(这可能就是为什么SharedPreferences文档说"目前这个类不支持跨多个进程使用.这将在以后添加.")
MODE_MULTI_PROCESS只需与每次Context.getSharedPreferences(String name, int mode)调用一起使用:当您检索SharedPreferences的实例时,指定MODE_MULTI_PROCESS标志android将重新加载首选项文件,使其与发生的任何(最终)并发修改保持同步.如果您将该实例保留为类(静态或非静态)成员,则不会再次重新加载首选项文件.
使用Context.getSharedPreferences(...)你想要写或读入的喜好,每次不是过程,无论是安全的,但我想这可能是你可以在瞬间得到它最接近的一次.
如果您实际上不需要从不同的进程中读取相同的首选项,那么解决方法可能是为不同的进程使用不同的首选项文件.
pas*_*ssy 16
有完全相同的问题,我的解决方案是为SharedPreferences编写一个基于ContentProvider的替换.它可以100%多进程工作.
我把它变成了我们所有人的图书馆.结果如下:https: //github.com/grandcentrix/tray
我刚遇到同样的问题.我切换了我的应用程序在一个单独的进程中运行服务,并实现sharedPreferences全部被打破.
两件事情:
1)你在使用Editor.apply()或.commit()?我在用.apply().我在活动或服务对其进行更改后开始检查我的首选项文件,并且无论何时进行更改都会实现,它将创建一个仅包含新更改值的新文件.IE,当从服务写入/更改新值时,将从活动写入的值被擦除,反之亦然.我切换到.commit()任何地方,现在不再是这样了!从文档:"请注意,当两个编辑器同时修改首选项时,最后一个编辑应用获胜.
2)SharedPreferencesListener即使在切换到之后,似乎也不能跨进程工作.commit().您必须使用Messenger Handlers或Broadcast Intents来通知更改.当你查看SharedPreferences类的文档时,它甚至会说"注意:目前这个类不支持跨多个进程使用.这将在以后添加." http://developer.android.com/reference/android/content/SharedPreferences.html
在这方面,我们很幸运,我们甚至让MODE_MULTI_PROCESS标志SharedPreferences在不同的进程中从同一个进行读/写.
| 归档时间: |
|
| 查看次数: |
13118 次 |
| 最近记录: |