Распространения состояния - это типичная проблема при многозадачности, будь-то многозадачность в ОС, клиент-сервер или что-то еще, к счастью встречается не часто, поскольку ОС и прикладные средства многое делают за нас, но рано или поздно встречается в очередном проекте, в той или иной форме.
Здесь нужно аналитическое мышление, но не простое, а с хронологией по времени и ветвлениями, можно сказать "аналитическое алгоритмическое".
Возможно, у кого-то с рождения развито больше, у кого-то - меньше, но все равно развивать его в любом случае нужно, и в любом случае можно, если практиковаться.
Я не буду давать готового решения вашей проблемы, а опишу, как такие проблемы решать, постараюсь показать именно на примере Android и именно на вашей, я их уже решал успешно, а значит, если будете ориентироваться на предлагаемый мной план, то в итоге решите и эту, и другую.
Собственно и так не понятно кто/где и в какой момент инстанцирует экземпляр сервиса и активити
Для начала нужно ответить именно на эти вопросы, то есть изучить lifecycle для Activity и для Service.
Это делается даже без чтения документации и исходного кода, просто проводятся несложные эксперименты: перекрываются методы onCreate, onDestroy и ставится на них логирование, затем делаете разные действия (прежде всего нужно поискать в настройках что пользователь может завершить вручную отдельно от остального, я и так скажу -
Service можно, Activity нет), сами методы onCreate, onDestroy не статические, значит вызываются в каком-то экземпляре, ну, а придумать, как проверить тот ли это экземпляр или при этом создается новый - труда не составляет.
Это можно назвать "анализом алгоритма Android", того, который в API Android.
Следующий этап - "синтез разных вариантов нашего алгоритма и их анализ", нужно представить две координатные прямые по времени - Service и Activity, и "прокрутить" в голове все возможные варианты.
Например, у вас может возникнуть такая идея:
1) Создаем BroadcastReceiver в Service.
2) Затем из Service запускаем Activity.
3) Она при запуске посылает sendBroadcast, при завершении тоже.
4) Service его получает и узнает состояние Activity.
Вроде бы, идея верная.
Но мы знаем, что Service может быть завершен отдельно от Activity и запущен заново, а Android никак не оповестит об этом Activity, а значит, возможен такой вариант:
1) Создаем BroadcastReceiver в Service. Он по умолчанию знает, что Activity не запущена, и это
истина.
2) Затем из Service запускаем Activity.
3) Она при запуске посылает sendBroadcast(started), запущенный ранее ресивер его принимает, результат - Service знает, что Activity запущена, и это
истина.
4) Но затем Service завершается отдельно, значит и BroadcastReceiver - тоже, затем запускается новый Service , но Activity не запускается заново и поэтому нового sendBroadcast(started) она не отправляет, и второй Service снова по умолчанию знает, что Activity не запущена, а теперь это -
ложь, ведь она все еще запущена с первого раза.
Рекомендую так же проанализировать ваш вариант с Preferences, если в нем не будет таких "багов", то это уже хорошо, несмотря на топорность. :)
Хотя не такое уж и топорное, сам UNIX многое хранит в файлах, и что.
Зато такой анализ полезнее, чем просто найти готовое решение в Android и надеяться, что вы все правильно сделали и что оно подойдет (хорошо, если это вообще так).