ボクココ

個人開発に関するテックブログ

複数アプリ間でSharedPreferenceを使ったときのキャッシュ問題

いやーこれはやられた。

Context.MODE_WORLD_READABLEで保存したSharedPreferenceを外部から読み込むときに getSharedPreference が ShardPreference インスタンスがキャッシュしてるせいで、保存元のアプリでSharedPreferenceの中身を保存しても参照するアプリ側で変更をキャッチできなかった。

原因は、getSharedPreference の第二引数を Context.MODE_PRIVATE にしていたせいだった。 MODE_MULTI_PROCESS にすればOK。

Context exContext = mContext.createPackageContext(Musee.MUSEE_APP_PKG, Context.CONTEXT_RESTRICTED);
SharedPreferences mSharedPreferences = exContext.getSharedPreferences(Musee.MUSEE_PREF, Context.MODE_MULTI_PROCESS);

getShardPreference はこんなコードになっているらしい

  @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;
            }
        }
        if ((mode & Context.MODE_MULTI_PROCESS) != 0 ||
            getApplicationInfo().targetSdkVersion < android.os.Build.VERSION_CODES.HONEYCOMB) {
            sp.startReloadIfChangedUnexpectedly();
        }
        return sp;
    }

んで、下のほうのstartReloadIfChangedUnexpectedly、これがキャッシュの更新をしてくれるメソッドのようで、MODE_MULTI_PROCESSが大事だった。

Android 2系でもサポートライブラリのおかげか、ちゃんと動いた。良かった良かった。