2

I am making a simple budget tracking app. I have a Budget class that stores a few variables: the amount, duration, and initial value of budget. I only have one global Budget object inside the fragment, called "budget", and am trying to get it to save. It seems to save fine, but when I try to retrieve it, it returns the default value for some reason. Here are my methods for saving and loading. I only call getBudget() in onCreateView, and only call saveBudget in onResume() and after the budget is edited. Note the log entries.

public void saveBudget(){
    SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedPref.edit();
    editor.clear();
    Gson gson = new Gson();
    String json = gson.toJson(budget);
    Log.d("BTAG", "JSON: " + json);
    editor.putString("current budget", json);
    editor.commit();
 }

public Budget getBudget(){
    SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
    Gson gson = new Gson();
    String json = sharedPref.getString("current budget", null);
    Log.d("BTAG", "gson from json: " + gson.fromJson(json, Budget.class));
    return gson.fromJson(json, Budget.class);
}

My log says this for my current instance of Budget:

D/BTAG: JSON: {"amount":35.92,"frequency":"monthly","originalAmount":35.92}
D/BTAG: gson from json: null

This shows that it saves without issue, but loading doesn't work. Why is getBudget() not working?

drypotato
  • 27
  • 5
  • Can You Log `json` string in `getBudget()`? Maybe the problem is in converting and You receive correct string from shared preferences. – iknow Jul 15 '20 at 19:23
  • Just checked, it's showing null for json in getBudget too – drypotato Jul 15 '20 at 19:29

1 Answers1

2

I think the problem might be in:

only call saveBudget in onResume()

  1. You have to save the budget when the app is closing not in onResume(). Check this Android Activity Lifecycle.
  2. Also, I think You shouldn't use hardcoded strings as key. Try to use string resources as in Android docs. If You make a mistake in 'key' You will get the default value.
  3. If You save budget and then load it in another activity the problem might be in getting SharedPreferences instance. To get SharedPreferences use:
SharedPreferences sP = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

SharedPreferences from different activity

You can try this, I hope this will compile:

public static final String SHARED_PREFS = "NAME_OF_SP";
public static final String NAME_OF_VAL = "budget";

public void saveBudget()
{
    SharedPreferences sharedPref = getSharedPreferences(SHARED_PREFS, MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedPref.edit();
    Gson gson = new Gson();
    String json = gson.toJson(budget);
    Log.d("BTAG", "JSON: " + json);
    editor.putString(NAME_OF_VAL, json);
    editor.apply();
}

public Budget getBudget()
{
    SharedPreferences sharedPref = getSharedPreferences(SHARED_PREFS, MODE_PRIVATE);
    Gson gson = new Gson();
    String json = sharedPref.getString(NAME_OF_VAL, null);
    Log.d("BTAG", "gson from json: " + gson.fromJson(json, Budget.class));
    return gson.fromJson(json, Budget.class);
}
iknow
  • 8,358
  • 12
  • 41
  • 68
  • I actually had it it onResume() because the input for Budget is give in another activity. I just put it into onPause() and onDestroy() but it's still the same problem. – drypotato Jul 15 '20 at 19:30
  • @drypotato so You use `saveBudget` and `getFunction` in different activities? – iknow Jul 15 '20 at 19:34
  • Nope, all saving and getting is done in my BudgetFragment.java class. I have another class, createBudget.java, where I call BudgetFragment.budget to set variables from user input. So in the other activity I still access the static budget variable in BudgetFragment. – drypotato Jul 15 '20 at 19:39
  • You can check my edit in answer and try to make `SharedPreferences` instance in another way. If it wouldn't help then I have no idea where is problem :/ – iknow Jul 15 '20 at 19:44
  • No problem, thanks for trying! I'll post a solution when I figure out the issue. – drypotato Jul 15 '20 at 19:59
  • Okay, last try. I added a new full code, You can try and switch it with Yours. It should compile but I am not sure cause in my Project I didn't have `Gson` and `Budget` class. I deleted a clear method and get SP in another way. – iknow Jul 15 '20 at 20:13
  • 1
    This works perfectly! Thank you so much! Do you know why this works and my implementation didn't? – drypotato Jul 15 '20 at 20:21
  • 1
    @drypotato I am so happy! I am not sure but I changed 3 things. I removed `editor.clear();`. Changed `editor.commit();` to `editor.apply();`. And also change the way of getting `SharedPreferences` instance. You can try in Your code to change only one of these things and then You will know where exactly was the problem. – iknow Jul 15 '20 at 20:33