Android: Как заставить onStartCommand () вызываться перед onBind ()?

Я пытаюсь создать липкую службу, которая может быть привязана (мне нужно запустить потенциально асинхронные операции в фоновом режиме на некоторые данные, которые хранится в службе). Для этого мне нужно быть уверенным, что onBind всегда запускается после onStartCommand. Есть ли способ гарантировать это?

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

Взятые из документов:

IntentService – это базовый класс для служб, которые обрабатывают асинхронные запросы (выраженные как намерения) по требованию. Клиенты отправляют запросы через вызовы startService (Intent); Служба запускается по мере необходимости, обрабатывает каждое намерение по очереди с использованием рабочего потока и останавливается, когда заканчивается работа.

Пример IntentService :

 public class MyService extends IntentService { @Override protected void onHandleIntent(Intent intent) { if (intent != null) { // Do some work here, get Intent extras if any, etc. // ... // Once this method ends, the IntentService will stop itself. } } } 

Более подробную информацию о том, как создать IntentService можно найти здесь .

Это может обрабатывать ваши асинхронные операции. И если вам нужна какая-либо обратная связь, которая «сломает» асинхронную часть требования, вы можете использовать LocalBroadcastManager или, как вы сказали, вы можете привязываться к этой Service . И опять же, это зависит от того, что вы пытаетесь сделать.

Из документов у вас есть два типа услуг.

Начал

Служба запускается, когда компонент приложения (например, активность) запускает его, вызывая startService (). После запуска служба может работать в фоновом режиме на неопределенный срок, даже если компонент, который начал ее, будет уничтожен. Обычно запущенная служба выполняет одну операцию и не возвращает результат вызывающему. Например, он может загружать или загружать файл по сети. Когда операция завершена, служба должна остановиться сама.

граница

Служба «привязана», когда компонент приложения связывается с ней, вызывая bindService (). Связанная служба предлагает интерфейс клиент-сервер, который позволяет компонентам взаимодействовать с сервисом, отправлять запросы, получать результаты и даже делать это через процессы с межпроцессорной связью (IPC). Связанная служба запускается только до тех пор, пока к ней привязан другой компонент приложения. Несколько компонентов могут сразу связываться с сервисом, но когда все они отвязаны, служба уничтожается.

Напоминание: вы можете запустить Service через startService() чтобы она запускалась «неопределенно» и связывалась с ней, вызывая onBind() позже.

 Intent it = new Intent(this, MyService.class); startService(it); // Start the service. bindService(it, this, 0); // Bind to it. 

Если вы хотите просто запустить эту службу до тех пор, пока ваша Activity запущена, вы можете просто вызвать onBind() .

 Intent it = new Intent(this, MyService.class); bindService(it, this, 0); // This will create the service and bind to it. 

Более подробную информацию о сервисе «по умолчанию», о том, как его использовать и реализовать, можно найти здесь .

Просто выберите то, что лучше всего подходит для вашего случая использования, и вам хорошо идти.

Дело в том, что вы не должны вызывать как startService (), так и bindService (). Если вы хотите привязываться к службе, вызовите функцию bindService (). Когда услуга подключена, вызывается реализация ServiceConnection.onServiceConnected (), предоставляя вам IBinder службе. Как правило, связанная служба используется в качестве серверной части внутреннего интерфейса клиент-сервер. Вы связываетесь с сервисом, возвращаете IBinder, который дает вам дескриптор самого объекта службы, а затем используйте дескриптор Service для передачи данных или методов вызова в службе.

Связанные службы почти всегда используются для соединения между процессами (IPC).

Согласно документам :

Служба может по существу принимать две формы:

Начал
Служба запускается, когда компонент приложения (например, активность) запускает его, вызывая startService ().
граница
Служба «привязана», когда компонент приложения связывается с ней, вызывая bindService (). [..] Связанная служба работает только до тех пор, пока к ней привязан другой прикладной компонент. Несколько компонентов могут сразу связываться с сервисом, но когда все они отвязаны, служба уничтожается.

Чтобы убедиться, что onStartCommand() всегда выполняется до onBind() , продолжайте отправлять новое намерение службе в любое время, когда вы хотите привязываться к ней. Это связано с тем, что любое новое намерение службы вызовет onStartCommand() , а затем вызов bindService() будет выполнять onBind() .

Для любого решения проблемы сохранения. Вы можете вызвать функцию start в методе onBind.

 @Override public IBinder onBind(Intent intent) { //stars self Intent myIntent = new Intent(this, Service.class); startService(myIntent); //TODO return null; } 

Затем вы просто проверяете, запущен ли сервис или нет, и обрабатывайте его.