すみません、勘違いでした。
ContextImplクラスで staticに保持する Mapにおいて既に同じ名前のプリファレンスが利用されていれば、
それを利用してしまうので問題が起きていますね。ContextBの "foo"を利用する場合にも下記のコードで
sSharedPrefs.get("foo")が ContextAの物を返してしまいます。
@Override
public SharedPreferences getSharedPreferences(String name, int
mode) {
SharedPreferencesImpl sp;
synchronized (sSharedPrefs) {
sp = sSharedPrefs.get(name);
if (sp == null) {
File prefsFile = getSharedPrefsFile(name);
sp = new SharedPreferencesImpl(prefsFile, mode);
sSharedPrefs.put(name, sp);
return sp;
}
}
--
な
On 4月4日, 午前11:04, 石畑恭平 <
ishihata.k.t...@gmail.com> wrote:
> 石畑です。
>
> MODE_MULTI_PROCESS のフラグを付けても、この問題は解消しないんです。
> ソースを読む限り、MODE_MULTI_PROCESS の指定はプロセス間の競合(と言うのかな?)を防ぐためのものです。
> 今回の問題は、同一プロセス内で複数のアプリの Context を扱う場合に発生するものですので、
> MODE_MULTI_PROCESS は関係ないと考えています。
>
> 2013年4月4日 10:32 Tatsuo Nagamatsu <
nagam...@gmail.com>:
>
>
>
>
>
>
>
> > Android 2.3より新しいターゲットでは、複数プロセスからプリファレンスを共有する際には注意が必要です。
> > public static final int MODE_MULTI_PROCESS
> > Added in API level 11<
http://developer.android.com/guide/topics/manifest/uses-sdk-element.h...>
>
> > SharedPreference loading flag: when set, the file on disk will be checked
> > for modification even if the shared preferences instance is already loaded
> > in this process. This behavior is sometimes desired in cases where the
> > application has multiple processes, all writing to the same
> > SharedPreferences file. Generally there are better forms of communication
> > between processes, though.
>
> > This was the legacy (but undocumented) behavior in and before Gingerbread
> > (Android 2.3) and this flag is implied when targetting such releases. For
> > applications targetting SDK versions *greater than* Android 2.3, this
> > flag must be explicitly set if desired.
>
> >
http://developer.android.com/reference/android/content/Context.html#M...
>
> > 2013/4/4 ishihata <
ishihata.k.t...@gmail.com>
>
> >> こんにちは。石畑と申します。
>
> >> nemoさんの投稿からだいぶ経ってしまっていますが、私も同じ現象にぶち当たりました。
> >> Android 2.3.3 エミュレータではこの問題は発生しないのですが、
> >> Android 4.1.2 エミュレータと Xperia VL (Android 4.0.4)実機では発生します。
> >> Android 2.3.3 のソースは見ていないのですが(ソースの取得がちょっと面倒そうなので…)、
> >> 昔の実装ではキャッシュしてなかったのかなと推察しています。
>
> >> Android の Issue tracker にはまだそれらしい投稿がありませんでしたので
> >> 僭越ながら軽く投稿しておきました。
> >>
https://code.google.com/p/android/issues/detail?id=53900
>
> >> とりあえずの回避策としては、SharedPreferences のファイル名を
> >> (パッケージ名を含めるなどして)ユニークにする、くらいですかね?
>
> >> 2012年5月5日土曜日 13時16分54秒 UTC+9 nemo:
>
> >>> こんにちは。
> >>> Context#getSharedPreferences が返すインスタンスは通常,**
> >>> 各パッケージローカルのデータディレクトリーと対応づけられてい**ると思います。
> >>> SharedPreferences prefA = pkgContextA.**getSharedPreferences("foo",
> >>> ...);
> >>> SharedPreferences prefB = pkgContextB.**getSharedPreferences("bar",
> >>> ...);
> >>> ならば,prefA は /data/data/domain.**packageNameA/shared_prefs/foo.**xml
> >>> に,prefB は/data/data/domain.**packageNameB/shared_prefs/bar.**xml
> >>> に紐付いています。
>
> >>> ですが
> >>> SharedPreferences prefA = pkgContextA.**getSharedPreferences("foo",
> >>> ...);
> >>> SharedPreferences prefB = pkgContextB.**getSharedPreferences("foo",
> >>> ...);
> >>> としたとき,prefA と prefB は同じインスタンスで, /data/data/domain.**
> >>> packageNameA/shared_prefs/foo.**xml に紐付いています。
>
> >>> これは, #getSharedPreferences の実装が, ContextImpl
> >>> のstaticコンテキストでSharedPreference のインスタンスをキャッシュしており(いわゆるクラスメンバー)**,
> >>> そのキャッシュを検索する際のキーが("contextA/**foo" などではなくて単に) "foo" となっているためで,なんといいますか,*
> >>> *意図的にそうしたわけではないような感じがします。
> >>> 回避策が自明なので放置されているのかな?
>
> >>> わたし,何か勘違いしてますでしょうか。ツッコミとか,**先行議論とかご存じのかたいらっしゃいましたら反応ください。