Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set and get Singleton object of a model class using dagger2?

What options do I have to make a single instance of all the models classes in an Android application?

I have added below one of the sample model classes

public class User
{
    private String email;
    private String name;
    public String getEmail()           {  return this.email;    }
    public void setEmail(String email) {  this.email = email;   }
    public String getName()            {  return this.name;    }
    public void setName(String name)   {  this.name = name;   }
}

I want that once data is stored in the Model Class, it can be retrieved in any activity, class, or fragment. Should I use a singleton, or is there any better approach available ?

Will dagger2 work in this scenario? Is dagger2 an alternative to creating a singleton?

Thanks

like image 974
Muhammad Irfan Avatar asked Oct 20 '22 08:10

Muhammad Irfan


1 Answers

============ Question 1 - What options do I have... ===============

There are many pitfalls to using Singletons in Android. The biggest of which is that Android manages the life-cycle of your application. Thus any activity could be destroyed at any time. Or Android may even choose to kill your process if memory is needed for other purposes. Android will restore your app/activity, however if you do nothing, state is lost. In the process-kill scenario, you have a new instance of the VM, and any state in Singleton objects is lost. Of course if you code with care, you can ensure that these are appropriately re-created with the correct state. This can be hard and error-prone.

If you need these model classes available from any activity in your app, there are several somewhat better approaches you can take:

Option 1.

i. Pass the objects from activity to activity using Intents. This solves the "globally available" problem. This will also require you to make your model classes Parcelable or serializable. ii. Use the onSaveInstanceState method to save the state of objects in your activity. Restore the state in the onCreate method. This process is described here.

What might be awkward about this approach is the overhead and extra code required to always write-to and read-from Intent on every activity transition.

Option 2

Consider having your singletons persist their data on every write, and read from persistence on every read. You have multiple persistence mechanisms at your disposal including: SharedPreferences, Basic File I/O, and SQL Database. These options are discussed here: http://developer.android.com/guide/topics/data/data-storage.html. If you go this route, personally I have found SharedPreferences to be the easiest to work with.

Here is an example of how it might be done

public class User {

    //---------------------
    // Singleton implementation.  Note this is just one of several styles
    // of this pattern.
    private static User instance = new User();
    private User() {} // prevent instantiation
    public User getUserInstance() { return instance; }
    //---------------------

    private String category = "user_bean_settings";
    private String emailKey = "email";
    private String nameKey = "name";

    public String getEmail() {
        return readStringProperty(emailKey);
    }
    public void setEmail(String email) {
        writeStringProperty(emailKey, email);
    }
    public String getName() {
        return readStringProperty(nameKey);
    }
    public void setName(String name) {
        writeStringProperty(nameKey, name);
    }

    private String readStringProperty(String prop) {
        Context context = getApplicationContext();
        SharedPreferences prefs = context.getSharedPreferences(category, Context.MODE_PRIVATE);
        return prefs.getString(prop, null);
    }

    private void writeStringProperty(String prop, String value) {
        Context context = getApplicationContext();
        SharedPreferences prefs = context.getSharedPreferences(category, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = prefs.edit();
        editor.putString(prop, value);
        editor.commit();
    }
}

The one awkward part of this is that you will need to have a Context reference handy to access SharedPreferences. How best to do that is your call. Keep in mind that Activities themselves are Contexts so you can alway pass that. There are lots of different ways to handle this.

======= Question 2 - Is dagger2 an alternative to creating a singleton?... ==========

I looked at Dagger 2 and see that it is a dependency injection framework. There are many benefits to using a DI framework (loose coupling, testability, ...). You could use Dagger (or another DI framework like RoboGuice) to manage your singletons. If that is your only objective, I personally would not think it is worth the additional effort of integration. If however you want to enjoy some of the other benefits of DI mentioned above, then it might be worth your while. Keep in mind that these do not come for free, you still need to follow good coding practices. Anways, this seems to have gone a bit beyond the scope of the question.

like image 181
EJK Avatar answered Oct 22 '22 21:10

EJK