Intereting Posts
Как выровнять источник изображения в ImageButton? Могу ли я заставить IntelliJ отлаживать приложения для Android через устройство вместо эмулятора? Android с глубокой связью. Intent не сбрасывается, когда приложение открывается из истории Мастер плейера Roman Nurik's Wizard – как получить доступ к собранным данным? Небезопасный класс в Android? Android доступны mime-типы? Как включить доступ к местоположению программно в android? Как обнаружить пользователя руки, удерживающего его устройство Android: сканирование сети Wifi + выбираемый список Хранение видео для офлайн-использования в приложениях PhoneGap / Chrome Как отключить сбой CollapsingToolbar, когда прокрутка не имеет содержимого? Как программно загрузить Html-страницу в android и получить ее Html? Повторное использование просмотров в Android Listview с двумя различными макетами BackUpAgentHelperClass не вызван Обновление для Android SDK Tools R22

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

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

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

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

EDIT: Я хотел бы иметь мнения по нескольким аспектам:

  • синхронизация
  • Повторное использование
  • тестирование

Solutions Collecting From Web of "Синглтоны против контекста приложения в Android?"

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

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

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

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

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

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

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

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

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

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

От: http://developer.android.com/reference/android/app/Application.html

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

Приложение – это не то же самое, что Singleton. Причины:

  1. Метод приложения (например, onCreate) вызывается в потоке ui;
  2. Метод singleton можно вызывать в любом потоке;
  3. В методе «onCreate» приложения вы можете создать экземпляр Handler;
  4. Если singleton выполняется в ничейной нити, вы не можете создать экземпляр Handler;
  5. Приложение имеет возможность управлять жизненным циклом действий в приложении. У него есть метод «registerActivityLifecycleCallbacks». Но синглтоны не обладают способностью.

У меня была та же проблема: Singleton или сделать подкласс android.os.Application?

Сначала я попытался с помощью Singleton, но мое приложение в какой-то момент делает звонок в браузер

 Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com")); 

И проблема в том, что если в телефоне недостаточно памяти, большинство ваших классов (даже Singletons) очищаются, чтобы получить некоторую память, поэтому, возвращаясь из браузера в мое приложение, он разбивается каждый раз.

Решение: поместите необходимые данные в подкласс класса Application.

Рассмотрите оба вопроса одновременно:

  • Имеющие одноэлементные объекты как статические экземпляры внутри классов.
  • Имеющий общий класс (Context), который возвращает экземпляры singleton для всех объектов singelton в вашем приложении, что имеет то преимущество, что имена методов в Context будут иметь смысл, например: context.getLoggedinUser () вместо User.getInstance ().

Кроме того, я предлагаю вам расширить контекст, чтобы включить не только доступ к объектам singleton, но и некоторые функции, к которым необходимо получить доступ во всем мире, например, например: context.logOffUser (), context.readSavedData () и т. Д. Вероятно, переименование контекста в Тогда тогда будет смысл.

Они на самом деле то же самое. Есть одна разница, которую я вижу. С помощью класса Application вы можете инициализировать свои переменные в Application.onCreate () и уничтожить их в Application.onTerminate (). При использовании singleton вы должны полагаться на инициализацию VM и уничтожение статики.

Моя активность вызывает финиш () (которая не заставит его закончить сразу, но в конце концов) и вызывает Google Street Viewer. Когда я отлаживаю его на Eclipse, мое соединение с приложением прерывается при вызове Street Viewer, которое я понимаю как закрывающее (целое) приложение, предположительно для освобождения памяти (поскольку одно завершаемое действие не должно вызывать такого поведения) , Тем не менее, я могу сохранить состояние в Bundle через onSaveInstanceState () и восстановить его в методе onCreate () следующего действия в стеке. Либо используя статическое одноэлементное или подклассическое приложение, я сталкиваюсь с закрытием и потерей приложения (если только я не сохраняю его в Bundle). Поэтому по моему опыту они одинаковы в отношении сохранения государства. Я заметил, что соединение потеряно в Android 4.1.2 и 4.2.2, но не на 4.0.7 или 3.2.4, что, по моему мнению, говорит о том, что механизм восстановления памяти в какой-то момент изменился.

Мои 2 цента:

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

Мое дело было очень простым: у меня просто есть приватная «init_done» и статический метод «init», который я вызывал из activity.onCreate (). Я замечаю, что метод init был повторно запущен при некотором воссоздании активности.

Хотя я не могу подтвердить свое утверждение, это может быть связано с WHEN, когда singleton / class был создан / использован первым. Когда активность уничтожается / перерабатывается, кажется, что весь класс, который относится только к этому виду деятельности, также перерабатывается.

Я перенес экземпляр singleton к подклассу приложения. Я присоединяюсь к ним из экземпляра приложения. И с тех пор еще не заметил проблему.

Надеюсь, это поможет кому-то.

Из уст пресловутой лошади …

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

При написании приложения для Android у вас будет только один экземпляр класса android.app.Application, и поэтому он безопасен (и рекомендован командой Google Android) для обработки его как сингла. То есть вы можете безопасно добавить статический метод getInstance () в свою реализацию приложения. Вот так…

 public class AndroidApplication extends Application{ private static AndroidApplication sInstance; public static AndroidApplication getInstance(){ return sInstance; } @Override public static void onCreate(){ super.onCreate() sInstance = this; } }