Skip to content Skip to sidebar Skip to footer

Singleton Returning Two Instances

I'm trying to use a singleton (PhotoStorage) to provide an arrayList of Photo objects, but it seems that the PhotoStorage instance is not behaving as a singleton (two instances). I

Solution 1:

You are not executing Singletton pattern in the correct way,

The Singleton design pattern addresses all of these concerns. With the Singleton design pattern you can: Ensure that only one instance of a class is created Provide a global point of access to the object

In your case, we don't see PhotoStorage class but this call comes from an instance, what is not allowed by Singletton pattern:

photoStorage.get(mAppContext).savePhotosToFile();
//↑ instance call WRONG!!

This line works, but as your get method is static is not a good practice as Karakuri pointed and also breaks the Singletton pattern definition.

publicstaticPhotoStorageget(Context c){

SOLUTION To make photoStorage.get() invalid and create a correct Singletton pattern you must:

  • declare the getInstance() method static in the class (here PhotoStorage)
  • hide default constructor to avoid instances of the class
  • create private constructors if necessary
  • call getInstance() it in a static way:

classPhotoStorage { 
    // hidding default constructorprivatePhotoStorage () {};

    // creating your own constructor but private!!!privatePhotoStorage(Context appContext){
        mSerializer = new PhotoJSONer(appContext, PHOTOS_DATABASE);
        try{
            mPhotos = mSerializer.loadPhotos();
        }catch(Exception e){
            mPhotos = new ArrayList<Photo>();
        }
    }

    //Singleton enforcementpublic synchronized static PhotoStorage get(Context c){
        if(sPhotoStorage == null){
            sPhotoStorage = new PhotoStorage(c.getApplicationContext());
        }
        return sPhotoStorage;
    }
}

Then you can make static call from everywhere the class scope allows:

@Override
publicvoidsavePhotos(){
      PhotoStorage.get(mAppContext).savePhotosToFile();
    //↑ static call CORRECT!!
}

UPDATE: if your app have several threads and singleton getInstance requests may overlapp, there is a double check syncronized singletton pattern you can apply:

//Singleton enforcementpublic synchronized staticPhotoStorageget(Context c){
    if(sPhotoStorage == null){
        synchronized(PhotoStorage.class) {
            if(sPhotoStorage == null) {
                sPhotoStorage = newPhotoStorage(c.getApplicationContext());
            }
        }
    }
}

Post a Comment for "Singleton Returning Two Instances"