Подтвердить что ты не робот

Android Singleton с глобальным контекстом

В документации на Android говорится:

Как правило, нет необходимости в подклассе Application. В большинстве случаев, статические синглеты могут обеспечивать такую ​​же функциональность в более модульной путь. Если ваш singleton нуждается в глобальном контексте (например, для регистрации широковещательные приемники), функция для ее получения может быть предоставлена Контекст, который внутренне использует Context.getApplicationContext(), когда сначала построим синглтон.

Как я могу создать статический синглтон с глобальным контекстом, чтобы он выжил при изменении текущей активности в моем приложении? Достаточно ли иметь статический контекст, который ссылается на getApplicationContext()?

4b9b3361

Ответ 1

другое редактирование вопроса:

в последнее время (по большей части 2016 года и вперед), что я делал, и было бы моим предложением для любого разработчика сделать это как:

Используйте Dagger2, просто используйте кинжал 2. Где вам нужно Context:

@Inject Context context;

и что он. В то время как на нем, добавьте все другие вещи, которые будут синглом.

отредактированный/улучшенный ответ:

потому что этот ответ становится популярным, я улучшу свой собственный ответ с примером кода того, что я использовал в последнее время (по состоянию на июль /2014).

Начните с того, что приложение сохраняет ссылку на себя.

public class App extends Application {
   private static App instance;
   public static App get() { return instance; }

   @Override
   public void onCreate() {
      super.onCreate();
      instance = this;
   }
}

тогда на любом одноэлементном узле, который нуждается в доступе к Context, я ленив загружаю синглы в потоковом режиме, используя двойную проверку синхронизации, как описано здесь fooobar.com/questions/65513/...

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();
}

оригинальный ответ:

то, что предлагает документация, - это использовать обычный одноэлементный шаблон

 public class SingletonDemo {
    private static SingletonDemo instance = null;

    private SingletonDemo() {       }

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

и включите внутри него такой способ:

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

и не забудьте вызвать это, чтобы инициализировать синглтон.

Разница между Прикладным подходом и подходом Singleton и почему Синглтон лучше всего находится в документации same functionality in a more modular way

Ответ 2

У меня такой класс в моем приложении:

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;
    }
}

а затем, например, в Launch Activity инициализируйте его:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //init
    ApplicationContext.getInstance().init(getApplicationContext());
    //use via ApplicationContext.get()
    assert(getApplicationContext() == ApplicationContext.get());
}