3

I'm a bit confusing on how to share global variables between activities in an android project that considered safe.

What is the best practice to do that? Extends Application class or make a custom singleton class?

An help is apprecciate, thanks in advance.

ligi
  • 39,001
  • 44
  • 144
  • 244
Augusto Picciani
  • 788
  • 2
  • 11
  • 31

2 Answers2

4

The problem with storing something in the application class is you cannot count on an activity being resumed from the same instance of the application object. For example an activity can be paused, the application killed (due to memory) along with any changes you made to object in the instance, and then the activity resumed with a new application instance.

Here is a very good BLOG post explaining how data stored in the application class can be lost: http://www.developerphil.com/dont-store-data-in-the-application-object

I am not sure this is the very "Best" practice, but I think this is a good solution

I have a PersistData class holds application wide "globals". I use Dagger to inject instances of this singleton into any class that requires these variables.

The basic process it this:

When I save a value in this object via something like:

mPersistData.saveEmailId("me@example.com");
  1. I first write it to an entry in SharedPreferences
  2. I then save it to a member variable

In the constructor for the class, I initialize the member variables by reading them from SharedPreferences. This way reads for the variable are "cached", ie they don't need to be read from SharedPreferences, and if the application is ever killed and restarted the member variables have the correct values. If you just hold the values in the application class, when the application is restarted the member variables will be invalid (not what you expect or even null).

Here is an example:

public class PersistData {
    private String email; 
    public PersistData(MyApp app) {
        mApp = app;
        email = readEmailId();

    }

    public void saveEmailId(String emailToSave) {
        writeEmailId(emailToSave);
        email = emailToSave;
    }

    private void writeEmailId(String emailId) {
        generalSettingsFileEditor.putString("USER_ID", emailId);
        generalSettingsFileEditor.commit();
    }

    public String readEmailId() {
        String emaiId = generalSettingsFile.getString("USER_ID","");
        return(emaiId);
    }

    public String getEmail() {
        return email;
    }
}

In my application Dagger module I have this:

@Provides @Singleton
public PersistData providePersistData () {
    System.out.println(String.format("mApp = %s", mApp));
    return new PersistData(mApp);
}

Then whenever I need to access any of these variables I inject the singleton as so:

public class HomePresenter {
    @Inject
    PersistData mPersistData;
    ...

    mPersistData.saveEmailId("me@example.com");
    myEmail = mPersistData.getEmailId();

   ...
}
nPn
  • 16,254
  • 9
  • 35
  • 58
0

What is the best practice to do that? Extends Application class or make a custom singleton class?

  1. Think twice whether those variables are really global and they have to be shared between activities.
  2. If the answer to first question is 'yes', then the best place would be to store them in Application.

You can implement a singleton too, but 1) it's slightly more difficult to test and b) if your global variables require Context, then again Application instance would fit the best.

sergej shafarenka
  • 20,071
  • 7
  • 67
  • 86