Android

Singletons vs. Application Context in Android?

Синглтоны против Контекст приложения в Android?

Вспоминая этот пост с перечислением нескольких проблем использования синглтонов и увидев несколько примеров приложений Android, использующих шаблон singleton, я задаюсь вопросом, хорошо ли использовать синглтоны вместо отдельных экземпляров, совместно используемых через глобальное состояние приложения (подкласс android.os.Application и получение его через context.getApplication()).

Какими преимуществами / недостатками будут обладать оба механизма?

Честно говоря, я ожидаю такого же ответа в этом посте Шаблон Singleton с веб-приложением, не очень хорошая идея! но применительно к Android. Я прав? Чем отличается DalvikVM в остальном?

РЕДАКТИРОВАТЬ: я хотел бы услышать мнения по нескольким связанным аспектам:


  • Синхронизация

  • Возможность повторного использования

  • Тестирование

Переведено автоматически
Ответ 1

Я в корне не согласен с ответом Дайан Хэкборн. Мы постепенно удаляем все синглтоны из нашего проекта в пользу легких объектов с ограниченным объемом задач, которые можно легко воссоздать, когда они вам действительно понадобятся.

Синглтоны - это кошмар для тестирования, и при ленивой инициализации они привносят "неопределенность состояния" с тонкими побочными эффектами (которые могут внезапно проявиться при перемещении вызовов в getInstance() из одной области видимости в другую). Видимость упоминалась как еще одна проблема, и поскольку синглтоны подразумевают "глобальный" (= случайный) доступ к общему состоянию, при неправильной синхронизации в параллельных приложениях могут возникать незначительные ошибки.

Я считаю это антишаблоном, это плохой объектно-ориентированный стиль, который по сути сводится к поддержанию глобального состояния.

Возвращаясь к вашему вопросу:

Хотя контекст приложения сам по себе можно считать синглтоном, он управляется фреймворком и имеет четко определенный жизненный цикл, область действия и путь доступа. Следовательно, я считаю, что если вам действительно нужно управлять глобальным состоянием приложения, это должно происходить здесь, нигде больше. Что касается чего-либо еще, подумайте, действительно ли вам нужен одноэлементный объект, или можно было бы также переписать ваш одноэлементный класс, чтобы вместо этого создавать экземпляры небольших недолговечных объектов, которые выполняют поставленную задачу.

Ответ 2

Я очень рекомендую синглтоны. Если у вас есть синглтон, которому нужен контекст, имейте:

MySingleton.getInstance(Context c) {
//
// ... needing to create ...
sInstance = new MySingleton(c.getApplicationContext());
}

Я предпочитаю синглтоны, а не приложения, потому что это помогает сделать приложение намного более организованным и модульным - вместо того, чтобы иметь одно место, где необходимо поддерживать все ваше глобальное состояние в приложении, каждая отдельная часть может позаботиться о себе сама. Также тот факт, что синглтоны лениво инициализируются (по запросу) вместо того, чтобы вести вас по пути предварительной инициализации в приложении.onCreate() хорош.

По сути, в использовании синглтонов нет ничего плохого. Просто используйте их правильно, когда это имеет смысл. В фреймворке Android их действительно много, чтобы поддерживать кэш загруженных ресурсов для каждого процесса и другие подобные вещи.

Также для простых приложений многопоточность не становится проблемой с синглтонами, потому что по замыслу все стандартные обратные вызовы к приложению отправляются в основном потоке процесса, поэтому у вас не будет многопоточности, если вы не введете ее явно через потоки или неявно, опубликовав контент-провайдера или service IBinder для других процессов.

Просто подумайте о том, что вы делаете. :)

Ответ 3

От: Разработчик > справочник - приложение


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


Ответ 4

Приложение - это не то же самое, что синглтон.Причины таковы:


  1. Метод приложения (например, onCreate) вызывается в потоке пользовательского интерфейса;

  2. метод singleton может быть вызван в любом потоке;

  3. В методе "onCreate" приложения вы можете создать экземпляр обработчика;

  4. Если синглтон выполняется в потоке none-ui, вы не смогли создать экземпляр Handler;

  5. Приложение имеет возможность управлять жизненным циклом действий в приложении.У него есть метод "registerActivityLifecycleCallbacks".Но у singletons такой возможности нет.

java android