Глобальные данные приложения и их хранение при разработке под OS Android. Singleton, Service или ...?
У меня небольшой опыт разработки и если мои решения кажутся абсурдными, прошу не судить строго.
При написании веб-приложения под Android, у меня была необходимость использовать данные, поступающие при авторизации пользователя. Этих данных немного: 4-6 строк и интовый идентификатор, я решил что достаточно будет сохранить эти данные в памяти приложения и обращаться к ним при необходимости. Для этого мне пришла в голову мысль использовать паттерн синглтона.
Мне показалось разумным не писать собственный синглтон, а сделать обычный класс, описывающий модель приходящих данных, и хранить экземпляр этого класса в глобальной переменной наследника класса Application, к которому есть доступ из любой Activity приложения +, как мне тогда казалось, пока жив Application - жив и весь процесс. Но действительность повернулась к моим идеям филейной частью.
Попался мне пользователь девайса Samsung S3 на Android 4.3, у которого в бекграунде висит столько приложений, сколько не потянул был мой старенький лаптоп. Плюс у него установлен какой-то Clean Master, обещающий вычищать память телефона (как-будто Dalvik'у своего GC не хватает).
Словом, как многие уже догадались, объект, хранящий данные пользователя, у меня частенько обнулялся, что приводило к крешу приложения. Там же обнулялись у меня четырехпоточный ScheduledExecutorService, в котором я собирал потоки с запросами к серверу и некоторые другие объекты, необходимые на уровне внутренней логики. Немногим позднее я вычитал, что в качестве одного из паттернов для веб-приложений гугл рекомендует использовать UI - ContentProvider - Service. Я успел подумать о том, чтобы использовать "внутренний" сервис в пределах жизни приложения в качестве хранилища пользовательских данных, но так и не нашел ниодного указания на то, что в сервисе ссылки смогут жить дольше, чем в синглтоне. Вся эта прелюдия была нужна для того, чтобы дать вам, уважаемая аудитория хабра, понять чего я пытаюсь добиться, и в заключении вопрос:
Что лучше использовать для хранения глобальных данных в памяти приложения?
1) Синглтон
2) Сервис
3) Хранить данные локально и при необходимости дергать их из / записывать в базу ?
4) ..(другое)..
Приложение может умереть в любой момент поэтому данные нужно где то сохранять.
Логика работы может выглядеть как то так:
Создается Application, в onCreate проверяете:
1) если данные есть SharedPreference, загружаем их от туда
2) если данных нет, загружаем с сервера и сохраняем в SharedPreference
1 и 2 не подойдёт, т.к. приложение умирёт и данные потеряются.
3 - хороший вариант, но если данных для хранения мало, то не совсем подойдёт.
возможно в данном случае лучше воспользоваться SharedPreferences. данные, сохранённые в SharedPreferences будут жить пока приложение не удалят, либо пока не очистят данные приложения через настройки.
Т.е. в андроиде не получится хранить какую-то стронг ссылку в течении жизни процесса независимо от активити? получается, если использовать ScheduledExecutorService то для каждого http-запроса нужно делать новый экземпляр этого класса (я понимаю, что в таком контексте можно и обычные треды применять, но механизм то существует)? Ну или тот же апачевский, массивный HttpClient, уже не получится применять, либо формировать его для каждого запроса?
да, стронг ссылку хранить не получится.
а вот для запросов не обязательно каждый раз создавать новый объект ScheduledExecutorService или HttpClient. обычно логику общения с сервером выносят в Service. но и здесь при "смерти" приложения всё обнулиться, и уже при старте придётся инициализировать экзекутор заново.
а вообще я бы порекомендовал для выполнения запросов воспользоваться каким-нибудь готовым решением, например Volley