Effective Java #3: Be Monoelvistic like the Singleton

I’ve added a new page in the Joshua Block Tribute section of my blog:

Enforce the Singleton

Elvis, courtesy of the Britannica Blog.

Elvis, courtesy of the Britannica Blog. See also elvis.com.

Singletons have a unique property: there is only one instance of a singleton in the whole system as far as the application is concerned.

On Android many people make the mistake of believing the Activity or any object returned by a getContext() call is a singleton.  But in fact it’s not.  It can be created, re-created, mocked, and otherwise destroyed at any time.

I like to describe Context as just a “gate keeper” that ensures you have a valid application running when you do things like save files to the disk or perform networking.

As far as I know the only kind of Context that is guaranteed to be a singleton on Android is the Context object returned by Context.getApplicationContext().

This is the recommended way to get a global context on Android.  But there is another way as well, and it can serve as an in-memory data store for simple data items.  If you specify an Application derived object in your Android manifest (see the javadocs), you can safely get a singleton object that is unique as long as your process is active:

public class MyApplication extends Application{
     private static MyApplication APP;

     public static String someValue;

     @Override
     public void onCreate(){
          THISAPP = (MyApplication)this;
     }

     /**
      * Very handy to have around when a thread doesn't have a context:
      *
      * new Thread{
      *    public void run(){
      *         String prop = MyApplication.getApp().getPreference("MYPROPERTY", null);
      *         ...
      *    }
      * }
      *
      */
     public void getPreference(String key, String defaultValue){ 
        SharedPreferences prefs = getDefaultSharedPreferences(this);
        return prefs.getString(key, defaultValue);
     }

     /*
      * Must use static factory form in this case because onCreate
      * is the only place to get a valid reference.
      *
      * Call 
      *            MyApplication myApp = MyApplication.getApp();
      * to get the application singleton with global scope.
      *
      */
     public static final MyApplication getApp(){
          if (THISAPP == null)
             throw new  IllegalStateException(
                  "the application has not been initialized");

          /*
           * THISAPP can be used to store some static data that multiple
           * activities can access.  Watch out for a different 
           * instance in your service, however - it may be running in 
           * a different process!
           */
          return THISAPP;
     }
}

Effective Java #2: Class Builders

I’ve added a new page in the Joshua Block Tribute section of my blog:

Class Builders

Bob-the-Builder-tv-01

“Can we build it. Yes we can!” (image source: starpulse.com)

Class builders help you replace complex and unreadable constructor parameter lists with something more intuitive.  While it may add slightly to the runtime of your application due to more function calls, the tradeoff in readability and maintainability is often worth it.

You could even make the argument that replacing a gazillion constructor parameters for some optionally-used builder function calls improves performance.

Or … perhaps builders just help you not pull your hair out when reading code. I’ll let you decide.

Effective Java #1: Static Factory Methods

I’ve added a new page in the Joshua Block Tribute section of my blog:

Static Factory Methods

I-love-Lucy

This famous “I Love Lucy” episode depicts what you might experience if you make creating objects into a crazy mess. (image credit: Desilu Productions/Paramount, source: cornerstone-ct.com)

Using static factory methods can help keep the creation of objects from turning into an assembly line of hilarity.  That means:

  1. less code needed to use your masterpiece API,
  2. an easier time figuring out how to get your API to create the right objects.