1

I have an app that doesn't save shared preferences. I have tried using both commit() and apply() to save these preferences, but they are not saved once the application closes. If I change screens in my app, the changes are made but are lost when the app restarts.

Static method called when the app starts:

static {
        prefs = PreferenceManager.getDefaultSharedPreferences(MainActivity.getContext());//MainActivity.getContext().getSharedPreferences("LocationTimer", Context.MODE_PRIVATE);
        editor = prefs.edit();
        if(!prefs.contains("totalLocations")) {
            prefs.edit().putInt("totalLocations", 0).commit();
        }
        if(prefs.getInt("totalLocations", 0) == 0) {
            for (int i = 1; i <= COUNT; i++) {
                addItem(createLocationItem(i));
            }
            Log.i("PREFERENCES", "CREATED 1 LOCATION");
        } else {
            for (int i = 1; i <= prefs.getInt("totalLocations", 1); i++) {
                addItem(new LocationItem(String.valueOf(i), "Location " + String.valueOf(i), prefs.getString(String.valueOf(i), "")));
            }
            Log.i("PREFERENCES", "LOADED LOCATION(S)");
        }
        Log.i("PREFERENCES", "LOADED " + String.valueOf(prefs.getInt("totalLocations", 1)) +" LOCATION(S)");
    }

The message logged is "PREFERENCES: LOADED LOCATION(S)" and not "PREFERENCES: CREATED 1 LOCATION" so I know the item is being loaded and not simply created.

Method called when any item is created/loaded:

public static void addItem(LocationItem item) {
        ITEMS.add(item);
        ITEM_MAP.put(item.id, item);

        saveStringToPreferences(item.id, item.details);

        editor.putInt("totalLocations", ITEMS.size());
        editor.apply();

        Log.i("PREFERENCES", "CONTAINS " + String.valueOf(prefs.getInt("totalLocations", 1)) +" LOCATION(S)");
        Log.i("ITEMS", "CONTAINS " + String.valueOf(ITEMS.size()) +" LOCATION(S)");
    }

How I can tell this is saving the preferences while the app is already loaded is the above messages display other numbers besides one. One is the amount shown when the app loads.

Thanks for any help and suggestions. If you have any questions, please post and I will respond as soon as possible.

TheAnonymous010
  • 725
  • 7
  • 19
  • First, you're doing: `editor = prefs.edit();` but you're not using the editor. Second, `commit` returns a boolean value: it returns `true` if it saved successfully, you might want to check it! – Nir Alfasi May 22 '16 at 01:28
  • I actually do use the editor in the second code block. You are correct in that I do not use it in the first code block though. I will check if it returns true or false. Thanks for the help! – TheAnonymous010 May 22 '16 at 03:01
  • As a heads up, it commits successfully and returns `true`. It still does not save once the app restarts. – TheAnonymous010 May 22 '16 at 03:06
  • Are you using an emulator ? if you do - restarting it might fix the issue. See: http://stackoverflow.com/questions/15183224/app-keeps-forgetting-sharedpreferences-on-restart – Nir Alfasi May 23 '16 at 16:52
  • I was using an emulator and I had restarted it and my computer many times. Thanks for the suggestion though. – TheAnonymous010 May 24 '16 at 23:25

1 Answers1

0

For everyone having this kind of issue, my fix was to put the SharedPreferences into a dedicated class file. I created a file called AssetLoader.java and placed all of my SharedPreferences editing and initialization in their.

This is my AssetLoader file:

import android.content.Context;
import android.content.SharedPreferences;

import com.xenicdev.locationtimer.MainActivity;

public class AssetLoader {
    private static SharedPreferences prefs;

    public static void load() {

        // Prefs
        prefs = MainActivity.getContext().getSharedPreferences("LocationTimer", Context.MODE_PRIVATE);
        if(!prefs.contains("totalLocations")) {
            prefs.edit().putInt("totalLocations", 0).apply();
        }
    }

    public static void setTotalLocations(int totalLocations) {
        prefs.edit().putInt("totalLocations", totalLocations).apply();
    }

    public static Integer getTotalLocations() {
        return prefs.getInt("totalLocations", 0);
    }

    public static void setItemDetails(String id, String details) {
        prefs.edit().putString(id, details).apply();
    }

    public static String getItemDetails(String id) {
        return prefs.getString(id, "");
    }
}

In your Main file when its being created add:

AssetLoader.load();

And to call these methods in your other files add:

AssetLoader.getTotalLocations();

Another benefit of using this method is your other classes can be cleaned up quite a significant amount if you remove all of the SharedPreferences and simply use calls to your AssetLoader.

TheAnonymous010
  • 725
  • 7
  • 19