Проблема
Вам нужно получить доступ к глобальным данным из вашего приложения для платформы Android.
Решение
Лучшим решением является подкласс android.арр.Application
, который должен рассматриваться как синглтон (Singleton) со статическими методами доступа. У каждого приложения для платформы Android всегда есть один экземпляр класса android.арр.Application
на протяжении всей жизни приложения. Если вы выберете подкласс класса android.арр.Application
, то платформа Android создаст экземпляр вашего класса и вызовет из него методы жизненного цикла android.арр.Application
. Поскольку ничего не мешает вам создать другой экземпляр вашего подкласса android.арр.Application
, это не настоящий синглтон, но он достаточно похож на него.
Наличие глобального доступа к таким объектам, как обработчики сеансов, шлюзы веб-служб или что-либо еще, требующееся вашему приложению только в одном экземпляре, значительно упростит ваш код. Иногда эти объекты могут быть реализованы как синглтоны, а иногда нет, потому что им нужен экземпляр контекста для правильной инициализации.
В любом случае полезно добавить статические методы доступа к вашему подклассу класса android.арр.Application
, чтобы вы могли консолидировать все глобально доступные данные в одном месте, иметь гарантированный доступ к экземпляру класса Context и легко писать правильный код синглтона (Singleton), не беспокоясь о синхронизации.
При написании своего приложения для платформы Android вам могут потребоваться общие данные и службы в нескольких экземплярах класса Activity. Например, если ваше приложение имеет данные сеанса, такие как идентификатор пользователя, который в настоящий момент вошел в систему, вы, скорее всего, захотите предоставить эту информацию.
При разработке на платформе Android шаблон для решения этой проблемы состоит в том, чтобы ваш экземпляр класса android.арр.Application
располагал всеми глобальными данными, а затем обрабатывал ваш экземпляр приложения как синглтон со статическими методами доступа к различным данным и службам.
При написании приложения для платформы Android у вас будет только один экземпляр класса android.арр.Application
, поэтому его можно безопасно (в соответствии с рекомендациями команды Google Android) рассматривать как синглтон. Иначе говоря, вы можете безопасно добавить в свою реализацию приложения статический метод getlnstance()
. Образец такого кода приведен в примере 1.
public class AndroidApplication extends Application {
private static AndroidApplication sInstance;
private SessionHandler sessionHandler; // Обобщенный обработчик вашего приложения
public static AndroidApplication getInstance() {
return sInstance;
}
public Session Handler getSessionHandler()
return sessionHandler;
}
@Override
public void onCreate() {
super.onCreate();
sInstance = this;
sInstance.initializeInstance();
}
protected void initializeInstance() {
// Вся инициализация осуществляется здесь
sessionHandler = new SessionHandler(
this.getSharedPreferences( "PREFS_PRIVATE", Context.MODE_PRIVATE ) );
}
/** Это подходящее место для обработчика сеанса приложения; * обычно он описывается
независимым открытым классом.
*/
private class SessionHandler {
SharedPreferences sp;
SessionHandler(SharedPreferences sp) {
this.sp = sp;
}
}
}
Это не классическая реализация синглтона (Singleton), но с учетом ограничений платформы Android это самый близкий аналог, который у нас есть; он безопасен и работает.
Обработчик сеанса отслеживает информацию о каждом пользователе, такую как имя и, возможно, пароль или любую другую релевантную информацию, как в разных экземплярах класса Activity
, так и в одном и том же экземпляре этого класса, даже если он уничтожается и воссоздается. Наш класс SessionHandler
является заготовкой для того, чтобы вы могли написать такой обработчик, используя любую информацию, необходимую для поддержки активности!
Использование этого метода в данном приложении упростило и прояснило реализацию. Кроме того, это значительно облегчило разработку тестов. Используя эту технику в сочетании с каркасом тестирования Robolectric
, вы можете имитировать среду исполнения простым способом.
Кроме того, не забудьте добавить объявление класса приложения android:"name"
в существующий элемент application
в файле AndroidManitest.xml
:
<application android:icon="@drawable/app_icon"
android:label="@string/app_name"
android:name=".AndroidApplication">