1

I have extended my Application in my Android App in order to store the different typefaces I use within my application. Everything is working fine, however I am not understanding the singleton part of the code and what is the goal of the getInstance (I set a breakpoint there and it is never called, also if I change the name of the method the Application works fine as well). Could someone enlighten me about this pattern? I don't normally work with OOP so it might be a stupid question.

MyApplication.java

    public class MyApplication extends Application {
    private Typeface _typefaceNormal;
    private Typeface _typefaceBold;

    private static MyApplication singleton;

    public MyApplication getInstance() {
        return singleton;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        singleton = this;
        this._typefaceNormal = Typeface.createFromAsset(getAssets(),"PTS55F.TTF");
        this._typefaceBold = Typeface.createFromAsset(getAssets(), "PTS75F.TTF");
    }

    public Typeface getNormalFont() {
        return this._typefaceNormal;
        // return this._typefaceNormal;
    }

    public Typeface getBoldFont() {
        return this._typefaceBold;
        // return this._typefaceBold;
    }
}

And then I make the call like this:

this._typeface = ((MyApplication) _activity.getApplicationContext()).getNormalFont();

EDIT

From the answers I gathered, and some additional research, this was the class I ended up using:

    public class MyGlobalConfig {
    private static MyGlobalConfig singleton;
    private Typeface _typefaceNormal;
    private Typeface _typefaceBold;

    private MyGlobalConfig() {

    }

    public static MyGlobalConfig getInstance() {
        if (singleton == null) {
            singleton = new MyGlobalConfig();
        }
        return singleton;
    }

    public void init(Context ctx, String typefaceNormal, String typefaceBold) {
        this._typefaceNormal = Typeface.createFromAsset(ctx.getAssets(),
                typefaceNormal);
        this._typefaceBold = Typeface.createFromAsset(ctx.getAssets(),
                typefaceBold);
    }

    public Typeface getNormalFont() {
        return this._typefaceNormal;
        // return this._typefaceNormal;
    }

    public Typeface getBoldFont() {
        return this._typefaceBold;
        // return this._typefaceBold;
    }
}

I initialize it as:

MyGlobalConfig.getInstance().init(getApplicationContext(), normalFont, boldFont);

And set my Fonts as:

MyGlobalConfig.getInstance().getNormalFont();
Bernardo
  • 531
  • 1
  • 13
  • 31
  • As far as I know, you don't need singleton here since you (most probably) won't have two of your Application running at the same time. – guness Nov 26 '14 at 18:43
  • The `Application` *IS* a singleton - there is only ever one instance of it. Also, don't extend `Application` to do something as trivial as retrieving typefaces. – Squonk Nov 26 '14 at 19:27
  • @Squonk so what is the criteria? I thought that since, and I don't really know why, Android only lets us change the typeface programically, and since I use a lot of "setTypeFace" it would be a good place to store as a global variable – Bernardo Nov 26 '14 at 21:04
  • 1
    @Bernardo : I see you've accepted an answer from elevine and that would be the same approach I would use. Instead of extending `Application` and using it just for typefaces, create your own in the way elevine suggests. There are some reasons for extending `Application` but it's not normally required. – Squonk Nov 26 '14 at 22:19
  • @Squonk thanks ;) so for example, I will need to share some JSON objects (fetched from a Web Service) between my activities will that be a good reason to extend application? I edited my question in order to show the final code I am using. If you have any remarks please let me know (positive or negative) – Bernardo Nov 27 '14 at 10:49
  • @Bernardo : Your `MyGlobalConfig` class looks fine. It's basically the way I'd do it. – Squonk Nov 27 '14 at 11:11
  • @Squonk thanks once again for the help ;) – Bernardo Nov 27 '14 at 11:25

2 Answers2

2

The purpose of the singleton pattern is to enforce that only one instance of a class can be created. You don't really achieve that here though. The proper way to do it in Java is to make the constructor private and then set the static variable to the singleton instance of the class. For example:

public class MySingletonClass{
  private static MySingletonClass singleton;

  // private constructor
  private MySingletonClass(){}

  public static MySingletonClass getInstance(){
   if(singleton == null){
     singleton = new MySingletonClass();
   }
   return singleton;
  }
}

When it comes to working with Android, there is no need to make your Application class a singleton. Android will only create one instance of it and manage it for you. Also, since the Application class already has a public constructor defined, I don't believe that the compiler will allow you to make the constructor private in your extended class, so you couldn't enforce the singleton pattern.

Eric Levine
  • 13,536
  • 5
  • 49
  • 49
  • Oh ok...now that makes sense. My code is a group of various google searches but I saw a lot of getInstances that were never used. Would like to know why. But thank you very much for the explanation, it makes perfect sense :) – Bernardo Nov 26 '14 at 21:07
1

That's because you are not using the static method MyApplication.getInstance(). Instead, your are accessing the reference through the context.getApplicationContext() which in this case results in the same reference than the "singleton" static variable.

Accessing the instance through the static method getInstance() gives you the ability to access it without having a context reference, and saving you from casting ((MyApplication) _activity.getApplicationContext()). On the bad side, it couples your code and makes it less testeable.

Robert Estivill
  • 12,369
  • 8
  • 43
  • 64