Using Singleton within the Android Room Library

11,172

Solution 1

Singletons are considered evil because misusing them can make testing difficult. If the code being tested goes out and grabs a static singleton, then that singleton becomes difficult to mock for testing.

To mitigate the testing issue, your code should never get the singleton. Always receive it as a constructor parameter or have it injected by a DI framework. Of course, DI just moves the problem, because then the DI component becomes the singleton that your code reaches out and gets. But then you only have to figure out how to mock the DI component instead of a bunch of other things.

On Android, the Application is effectively a singleton, because only one instance is created per VM. So it's a good place to host other singletons like a DI component.

Solution 2

There are two way

1 ) you should be use dagger 2

2) make method in abstract RoomDatabase class which are provided object of class

Example:

@Database(entities = { Repo.class }, version = 1)
public abstract class RepoDatabase extends RoomDatabase {

    private static final String DB_NAME = "repoDatabase.db";
    private static volatile RepoDatabase instance;

    static synchronized RepoDatabase getInstance(Context context) {
        if (instance == null) {
            instance = create(context);
        }
        return instance;
    }

private RepoDatabase() {};

    private static RepoDatabase create(final Context context) {
        return Room.databaseBuilder(
            context,
            RepoDatabase.class,
            DB_NAME).build();
    }

    public abstract RepoDao getRepoDao();
}
Share:
11,172
ShaidK
Author by

ShaidK

Updated on June 04, 2022

Comments

  • ShaidK
    ShaidK about 2 years

    I have always been told that using Singleton were bad. However, every example of the Android Room implementation seems to use the Singleton approach. Can someone please explain why is this the case?

    Thanks

  • Martin Revert
    Martin Revert almost 6 years
    Can you explain why the getInstance() method is "static synchronized"?
  • DennisVA
    DennisVA almost 6 years
    synchronized because it would be possible to create two instances in multithreading scenario's. static should explain itself
  • Atikur Rahman Sabuj
    Atikur Rahman Sabuj about 4 years
    How can I access the instance?
  • Nikhil Vadoliya
    Nikhil Vadoliya about 4 years
    You can get access by this way : RepoDatabase.getInstance(context)
  • Alaa M.
    Alaa M. almost 4 years
    @NikhilVadoliya - you forgot to add public for getInstance(). By default it's private