Android Singleton with Global Context

前端 未结 2 1753
我寻月下人不归
我寻月下人不归 2020-11-28 03:28

Per the Android Documentation it states:

There is normally no need to subclass Application. In most situation, static singletons can provide the sam

相关标签:
2条回答
  • 2020-11-28 04:28

    I have such class in my application :

    public class ApplicationContext {
    
        private Context appContext;
    
        private ApplicationContext(){}
    
        public void init(Context context){
            if(appContext == null){
                appContext = context;
            }
        }
    
        private Context getContext(){
            return appContext;
        }
    
        public static Context get(){
            return getInstance().getContext();
        }
    
        private static ApplicationContext instance;
    
        public static ApplicationContext getInstance(){
            return instance == null ?
                    (instance = new ApplicationContext()):
                        instance;
        }
    }
    

    and then for example in Launch Activity initialize it :

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //init
        ApplicationContext.getInstance().init(getApplicationContext());
        //use via ApplicationContext.get()
        assert(getApplicationContext() == ApplicationContext.get());
    }
    
    0 讨论(0)
  • 2020-11-28 04:33

    Another edit to the question (2016)

    Lately (as of 2016 and onward) what I've been doing, and would be my suggestion for any developer, is:

    Just use Dagger 2. Wherever you need a Context you do:

    @Inject Context context;
    

    and that's it. While at it, inject all the other stuff that would be a singleton.

    Edited/improved answer (2014)

    because this answer is getting kinda-of popular, I'll improve my own answer with example code of what I've been using lately (as of Jul/2014).

    Start by having the application keeping a reference to itself.

    public class App extends Application {
       private static App instance;
       public static App get() { return instance; }
    
       @Override
       public void onCreate() {
          super.onCreate();
          instance = this;
       }
    }
    

    then on any singleton that needs access to the context I lazy load the singles in a thread safe manner using double check synchronization as explained here https://stackoverflow.com/a/11165926/906362

    private static SingletonDemo instance;
    
    public static SingletonDemo get() {
       if(instance == null) instance = getSync();
       return instance;
    }
    
    private static synchronized SingletonDemo getSync() {
       if(instance == null) instance = new SingletonDemo();
       return instance;
    }
    
    private SingletonDemo(){
       // here you can directly access the Application context calling
       App.get();
    }
    

    Original answer

    what the documentation is suggesting is to use a normal singleton pattern

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

    and include inside it a method like this:

     private Context context;
     init(Context context){
        this.context = context.getApplicationContext();
     }
    

    and remember to call this to initialise the singleton.

    The difference between the Application approach and the Singleton approach and why the Singleton is better is on the documentation same functionality in a more modular way

    0 讨论(0)
提交回复
热议问题