-2

I initiate a singleton instance in Application.onCreate, this instance has a member mApplicationContext which is initiated by getApplicationContext(), and this is the only place mApplicationContext be assigned value. From the crash log, mApplicationContext becomes null in certain scenarios, my question is in which this would happen?

public class ClassicSingleton {
   private static ClassicSingleton instance = null;
   private Context mApplicationContext = null;
   private ClassicSingleton() {
   }
   public static ClassicSingleton getInstance() {
      if(instance == null) {
         instance = new ClassicSingleton();
      }
      return instance;
   }

   public void initiate(Context context){
        this.mApplicationContext = context;
   }
}

public class MyApplication extends Application{
    @Override
    public void onCreate()
    {
        super.onCreate();
        ClassicSingleton.getInstance().initiate(getApplicationContext());
    }
}

I find similar question here Android static object lifecycle, but it didn't answer my question.

1 Answers1

0

Since you are writing a library, don't trust the caller to get it right. Check! i.e:

public void initiate(Context context){
     if (context == null) {
        throw new Error("Attempt to set null context");
     }
     if (mApplicationContext != null) {
        throw new Error("Why are you setting context twice?");
     }
     this.mApplicationContext = context.getApplicationContext();
}

Note the call to getApplicationContext ensures that you don't save an Activity context by mistake. An alternative would be to throw if context != context.getApplicationContext(), but that's probably overkill.

This doesn't fix your bug, but it will help you find it quickly.

Oh-- and you can probably find something better to throw than Error


Even better:

public static ClassicSingleton getInstance() {
   if(instance == null) {
      throw new Error("you forgot to initiate ClassicSingleton!");
   }
   return instance;
}

public static void initiate(Context context){
     if (context == null) {
        throw new Error("Attempt to set null context");
     }
     if (instance == null) {
        instance = new ClassicSingleton();
     }else{
        // optional
        throw new Error("Why are you initializing ClassicSingleton twice?");
     }
     instance.mApplicationContext = context.getApplicationContext();
}
Dale Wilson
  • 9,166
  • 3
  • 34
  • 52