org.bubenheimer.android.preference.SharedPreferencesUtility.java Source code

Java tutorial

Introduction

Here is the source code for org.bubenheimer.android.preference.SharedPreferencesUtility.java

Source

/*
 * Copyright (c) 2015-2017 Uli Bubenheimer.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package org.bubenheimer.android.preference;

import android.content.Context;
import android.content.SharedPreferences;
import android.support.annotation.NonNull;
import android.support.annotation.StringRes;
import android.support.annotation.UiThread;
import android.support.v4.util.Pair;
import android.support.v4.util.SimpleArrayMap;

import org.bubenheimer.android.log.Log;
import org.bubenheimer.util.Uninstantiable;

import java.util.ArrayList;
import java.util.List;

@SuppressWarnings({ "WeakerAccess", "unused" })
public final class SharedPreferencesUtility extends Uninstantiable {
    private static final String TAG = SharedPreferencesUtility.class.getSimpleName();

    private static final SimpleArrayMap<SharedPreferences, SimpleArrayMap<String, Pair<Integer, ? extends List<OnSharedPreferenceChangeListener>>>> masterMap = new SimpleArrayMap<>();

    private static final SharedPreferences.OnSharedPreferenceChangeListener masterListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
        @UiThread
        @Override
        public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) {
            final SimpleArrayMap<String, Pair<Integer, ? extends List<OnSharedPreferenceChangeListener>>> prefsEntry = masterMap
                    .get(sharedPreferences);
            if (prefsEntry == null) {
                Log.v(TAG, "Shared preferences not registered: ", sharedPreferences);
                return;
            }

            final Pair<Integer, ? extends List<OnSharedPreferenceChangeListener>> pair = prefsEntry.get(key);
            if (pair == null) {
                Log.v(TAG, "Shared preference not registered: ", key, " - ", sharedPreferences);
                return;
            }

            final List<OnSharedPreferenceChangeListener> list = pair.second;
            final int size = list.size();
            for (int i = 0; i < size; ++i) {
                list.get(i).onSharedPreferenceChanged(sharedPreferences, pair.first, key);
            }
        }
    };

    public interface OnSharedPreferenceChangeListener {
        @UiThread
        void onSharedPreferenceChanged(@NonNull final SharedPreferences sharedPreferences, @StringRes int id,
                @NonNull String key);
    }

    @UiThread
    public static void registerOnSharedPreferenceChangeListener(@NonNull final Context context,
            @NonNull final SharedPreferences prefs, @NonNull final OnSharedPreferenceChangeListener listener,
            @StringRes final int... resIds) {
        SimpleArrayMap<String, Pair<Integer, ? extends List<OnSharedPreferenceChangeListener>>> prefsEntry = masterMap
                .get(prefs);
        if (prefsEntry == null) {
            prefsEntry = new SimpleArrayMap<>();
            masterMap.put(prefs, prefsEntry);
            prefs.registerOnSharedPreferenceChangeListener(masterListener);
        }
        final int cnt = resIds.length;
        //noinspection ForLoopReplaceableByForEach
        for (int i = 0; i < cnt; ++i) {
            final int resId = resIds[i];
            final String key = context.getString(resId);
            Pair<Integer, ? extends List<OnSharedPreferenceChangeListener>> pair = prefsEntry.get(key);
            if (pair == null) {
                pair = Pair.create(resId, new ArrayList<OnSharedPreferenceChangeListener>());
                prefsEntry.put(key, pair);
            }
            pair.second.add(listener);
        }
    }

    @UiThread
    public static void unregisterOnSharedPreferenceChangeListener(@NonNull final Context context,
            @NonNull final SharedPreferences prefs, @NonNull final OnSharedPreferenceChangeListener listener,
            @StringRes final int... resIds) {
        final SimpleArrayMap<String, Pair<Integer, ? extends List<OnSharedPreferenceChangeListener>>> prefsEntry = masterMap
                .get(prefs);
        if (prefsEntry == null) {
            Log.w(TAG, "Shared preferences not registered: ", prefs);
            return;
        }
        final int cnt = resIds.length;
        //noinspection ForLoopReplaceableByForEach
        for (int i = 0; i < cnt; ++i) {
            final int resId = resIds[i];
            final String key = context.getString(resId);
            final Pair<Integer, ? extends List<OnSharedPreferenceChangeListener>> pair = prefsEntry.get(key);
            if (pair == null) {
                Log.w(TAG, "Shared preference not registered: ", key, " - ", prefs);
                return;
            }
            final List<OnSharedPreferenceChangeListener> list = pair.second;
            if (!list.remove(listener)) {
                Log.w(TAG, "Listener not registered: ", key, " - ", prefs);
                return;
            }
            if (list.isEmpty()) {
                prefsEntry.remove(key);
            }
        }
        if (prefsEntry.isEmpty()) {
            masterMap.remove(prefs);
            prefs.unregisterOnSharedPreferenceChangeListener(masterListener);
        }
    }
}