前人未踏の領域へ Androidアプリ開発編

Androidアプリ開発に関する調査メモ置き場。古い記事にはアプリ以外も含まれます。

SharedPreferenceでMODE_MULTI_PROCESSに関連するコード

getSharedPreferences()する際にMODE_MULTI_PROCESSをつけていると何をしてくれるのか。
Android 4.4のコードで確認。

1. android.app.ContextImpl.getSharedPreferencesでMODE_MULTI_PROCESSをチェック
    @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) {
            // If somebody else (some other process) changed the prefs
            // file behind our back, we reload it.  This has been the
            // historical (if undocumented) behavior.
            sp.startReloadIfChangedUnexpectedly();
        }
        return sp;
    }

2. android.app.SharedPreferencesImpl.startReloadIfChangedUnexpectedlyでsyncronizeしつつ読み込み

    void startReloadIfChangedUnexpectedly() {
        synchronized (this) {
            // TODO: wait for any pending writes to disk?
            if (!hasFileChangedUnexpectedly()) {
                return;
            }
            startLoadFromDisk();
        }
    }

MODE_MULTI_PROCESSをつけるとgetSharedPreferences()のたびに
startReloadIfChangedUnexpectedly()を実行してファイルから値を
再ロードするようになる。staticフィールドをsyncronizedしているだけだから
マルチプロセス下で同時に読み書きが発生するようなケースでは
期待した動作にならない可能性があるので注意が必要